Browse Source

add sidepanel and tabbed page #3830

pull/3978/head
Sony Thomas 10 months ago
committed by Thomas Kaul
parent
commit
508a23871b
  1. 3
      .vscode/settings.json
  2. 17
      apps/client/src/app/pages/resources/glossary/resources-glossary-routing.module.ts
  3. 16
      apps/client/src/app/pages/resources/glossary/resources-glossary.component.html
  4. 47
      apps/client/src/app/pages/resources/glossary/resources-glossary.component.scss
  5. 53
      apps/client/src/app/pages/resources/glossary/resources-glossary.component.ts
  6. 11
      apps/client/src/app/pages/resources/glossary/resources-glossary.module.ts
  7. 17
      apps/client/src/app/pages/resources/guides/resources-guides-routing.module.ts
  8. 16
      apps/client/src/app/pages/resources/guides/resources-guides.component.html
  9. 43
      apps/client/src/app/pages/resources/guides/resources-guides.component.scss
  10. 23
      apps/client/src/app/pages/resources/guides/resources-guides.component.ts
  11. 11
      apps/client/src/app/pages/resources/guides/resources-guides.module.ts
  12. 17
      apps/client/src/app/pages/resources/markets/resources-markets-routing.module.ts
  13. 16
      apps/client/src/app/pages/resources/markets/resources-markets.component.html
  14. 54
      apps/client/src/app/pages/resources/markets/resources-markets.component.scss
  15. 35
      apps/client/src/app/pages/resources/markets/resources-markets.component.ts
  16. 11
      apps/client/src/app/pages/resources/markets/resources-markets.module.ts
  17. 17
      apps/client/src/app/pages/resources/overview/resources-overview-routing.module.ts
  18. 16
      apps/client/src/app/pages/resources/overview/resources-overview.component.html
  19. 43
      apps/client/src/app/pages/resources/overview/resources-overview.component.scss
  20. 35
      apps/client/src/app/pages/resources/overview/resources-overview.component.ts
  21. 12
      apps/client/src/app/pages/resources/overview/resources-overview.module.ts
  22. 44
      apps/client/src/app/pages/resources/resources-page-routing.module.ts
  23. 20
      apps/client/src/app/pages/resources/resources-page.component.ts
  24. 286
      apps/client/src/app/pages/resources/resources-page.html
  25. 9
      apps/client/src/app/pages/resources/resources-page.module.ts
  26. 62
      apps/client/src/app/pages/resources/resources-page.scss
  27. 31
      package-lock.json
  28. 1
      package.json

3
.vscode/settings.json

@ -1,4 +1,5 @@
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
"editor.formatOnSave": true,
"vsicons.presets.angular": true
}

17
apps/client/src/app/pages/resources/glossary/resources-glossary-routing.module.ts

@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ResourcesGlossaryPageComponent } from './resources-glossary.component';
const routes: Routes = [
{
path: '',
component: ResourcesGlossaryPageComponent
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ResourcesGlossaryRoutingModule {}

16
apps/client/src/app/pages/resources/glossary/resources-glossary.component.html

@ -0,0 +1,16 @@
<div class="container">
<div class="row">
<div class="col">
<h1 class="h3 mb-4 text-center" i18n>Glossary</h1>
<div class="glossary-list">
@for (item of glossaryItems; track item) {
<div class="mb-4">
<h3 class="h5 mt-0">{{ item.term }}</h3>
<p class="mb-1">{{ item.definition }}</p>
<a target="_blank" [href]="item.link">Learn more →</a>
</div>
}
</div>
</div>
</div>
</div>

47
apps/client/src/app/pages/resources/glossary/resources-glossary.component.scss

@ -0,0 +1,47 @@
:host {
display: block;
padding: 1rem;
}
// Target the parent panel
:host-context(.mat-tab-nav-panel) {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
&::-webkit-scrollbar {
/* Chrome, Safari and Opera */
display: none;
}
}
.container {
max-width: 800px;
margin: 0 auto;
}
h1 {
margin-bottom: 2rem;
}
.glossary-list {
.mb-4 {
margin-bottom: 2rem;
}
h3 {
margin-bottom: 0.5rem;
}
p {
margin-bottom: 0.5rem;
}
a {
color: #007bff;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}

53
apps/client/src/app/pages/resources/glossary/resources-glossary.component.ts

@ -0,0 +1,53 @@
import { Component } from '@angular/core';
@Component({
selector: 'gf-resources-glossary',
templateUrl: './resources-glossary.component.html',
styleUrls: ['./resources-glossary.component.scss']
})
export class ResourcesGlossaryPageComponent {
public glossaryItems = [
{
term: 'Buy and Hold',
definition:
'Buy and hold is a passive investment strategy where you buy assets and hold them for a long period regardless of fluctuations in the market.',
link: 'https://www.investopedia.com/terms/b/buyandhold.asp'
},
{
term: 'Deflation',
definition:
'Deflation is a decrease of the general price level for goods and services in an economy over a period of time.',
link: 'https://www.investopedia.com/terms/d/deflation.asp'
},
{
term: 'Dollar-Cost Averaging (DCA)',
definition:
'Dollar-cost averaging is an investment strategy where you split the total amount to be invested across periodic purchases of a target asset to reduce the impact of volatility on the overall purchase.',
link: 'https://www.investopedia.com/terms/d/dollarcostaveraging.asp'
},
{
term: 'Financial Independence',
definition:
'Financial independence is the status of having enough income, for example with a passive income like dividends, to cover your living expenses for the rest of your life.',
link: 'https://en.wikipedia.org/wiki/Financial_independence'
},
{
term: 'FIRE',
definition:
'FIRE is a movement that promotes saving and investing to achieve financial independence and early retirement.',
link: '../en/blog/2023/07/exploring-the-path-to-fire'
},
{
term: 'Inflation',
definition:
'Inflation is an increase of the general price level for goods and services in an economy over a period of time.',
link: 'https://www.investopedia.com/terms/i/inflation.asp'
},
{
term: 'Stagflation',
definition:
'Stagflation describes a situation in which there is a stagnant economy with high unemployment and high inflation.',
link: 'https://www.investopedia.com/terms/s/stagflation.asp'
}
];
}

11
apps/client/src/app/pages/resources/glossary/resources-glossary.module.ts

@ -0,0 +1,11 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ResourcesGlossaryRoutingModule } from './resources-glossary-routing.module';
import { ResourcesGlossaryPageComponent } from './resources-glossary.component';
@NgModule({
declarations: [ResourcesGlossaryPageComponent],
imports: [CommonModule, ResourcesGlossaryRoutingModule]
})
export class ResourcesGlossaryPageModule {}

17
apps/client/src/app/pages/resources/guides/resources-guides-routing.module.ts

@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ResourcesGuidesComponent } from './resources-guides.component';
const routes: Routes = [
{
path: '',
component: ResourcesGuidesComponent
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ResourcesGuidesRoutingModule {}

16
apps/client/src/app/pages/resources/guides/resources-guides.component.html

@ -0,0 +1,16 @@
<div class="container">
<div class="row">
<div class="col">
<h1 class="h3 mb-4 text-center" i18n>Guides</h1>
<div class="guides-list">
@for (guide of guides; track guide) {
<div class="mb-4">
<h3 class="h5 mt-0">{{ guide.title }}</h3>
<p class="mb-1">{{ guide.description }}</p>
<a target="_blank" [href]="guide.link">Read more →</a>
</div>
}
</div>
</div>
</div>
</div>

43
apps/client/src/app/pages/resources/guides/resources-guides.component.scss

@ -0,0 +1,43 @@
:host {
display: block;
color: rgb(var(--dark-primary-text));
.container {
max-width: 800px;
margin: 0 auto;
}
h1 {
margin-bottom: 2rem;
}
.guides-list {
.mb-4 {
margin-bottom: 2rem;
}
h3 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-bottom: 0.5rem;
}
a {
color: rgba(var(--palette-primary-500), 1);
font-weight: 500;
text-decoration: none;
&:hover {
color: rgba(var(--palette-primary-300), 1);
text-decoration: underline;
}
}
}
}
:host-context(.theme-dark) {
color: rgb(var(--light-primary-text));
}

23
apps/client/src/app/pages/resources/guides/resources-guides.component.ts

@ -0,0 +1,23 @@
import { Component } from '@angular/core';
@Component({
selector: 'gf-resources-guides',
templateUrl: './resources-guides.component.html',
styleUrls: ['./resources-guides.component.scss']
})
export class ResourcesGuidesComponent {
public guides = [
{
title: 'Boringly Getting Rich',
description:
'The Boringly Getting Rich guide supports you to get started with investing. It introduces a strategy utilizing a broadly diversified, low-cost portfolio excluding the risks of individual stocks.',
link: 'https://herget.me/investing-guide'
},
{
title: 'How do I get my finances in order?',
description:
'Before you can think of long-term investing, you have to get your finances in order. Learn how you can reach your financial goals easier and faster in this guide.',
link: '../en/blog/2022/07/how-do-i-get-my-finances-in-order'
}
];
}

11
apps/client/src/app/pages/resources/guides/resources-guides.module.ts

@ -0,0 +1,11 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ResourcesGuidesRoutingModule } from './resources-guides-routing.module';
import { ResourcesGuidesComponent } from './resources-guides.component';
@NgModule({
declarations: [ResourcesGuidesComponent],
imports: [CommonModule, ResourcesGuidesRoutingModule]
})
export class ResourcesGuidesModule {}

17
apps/client/src/app/pages/resources/markets/resources-markets-routing.module.ts

@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ResourcesMarketsComponent } from './resources-markets.component';
const routes: Routes = [
{
path: '',
component: ResourcesMarketsComponent
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ResourcesMarketsRoutingModule {}

16
apps/client/src/app/pages/resources/markets/resources-markets.component.html

@ -0,0 +1,16 @@
<div class="container">
<div class="row">
<div class="col">
<h1 class="h3 mb-4 text-center" i18n>Markets</h1>
<div class="market-resources-list">
@for (resource of marketResources; track resource) {
<div class="mb-4">
<h3 class="h5 mt-0">{{ resource.title }}</h3>
<p class="mb-1">{{ resource.description }}</p>
<a target="_blank" [href]="resource.link">View resource →</a>
</div>
}
</div>
</div>
</div>
</div>

54
apps/client/src/app/pages/resources/markets/resources-markets.component.scss

@ -0,0 +1,54 @@
:host {
color: rgb(var(--dark-primary-text));
display: block;
.market-resources {
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
.mat-mdc-card {
height: 100%;
transition: border-color 0.3s ease;
&:hover {
border-color: var(--gf-theme-primary-500);
}
.mat-mdc-card-header {
.mat-mdc-card-title {
font-size: 1.1rem;
}
}
.mat-mdc-card-content {
font-size: 0.9rem;
}
.mat-mdc-card-actions {
padding: 0 1rem 1rem;
}
a {
color: rgba(var(--palette-primary-500), 1);
font-weight: 500;
text-decoration: none;
&:hover {
color: rgba(var(--palette-primary-300), 1);
text-decoration: underline;
}
}
}
}
}
:host-context(.theme-dark) {
color: rgb(var(--light-primary-text));
.market-resources {
.mat-mdc-card {
background-color: rgba(var(--palette-background-card-dark), 1);
}
}
}

35
apps/client/src/app/pages/resources/markets/resources-markets.component.ts

@ -0,0 +1,35 @@
import { Component } from '@angular/core';
@Component({
selector: 'gf-resources-markets',
templateUrl: './resources-markets.component.html',
styleUrls: ['./resources-markets.component.scss']
})
export class ResourcesMarketsComponent {
public marketResources = [
{
title: 'Crypto Coins Heatmap',
description:
'With the Crypto Coins Heatmap you can track the daily market movements of cryptocurrencies as a visual snapshot.',
link: 'https://www.tradingview.com/heatmap/crypto'
},
{
title: 'Fear & Greed Index',
description:
'The fear and greed index was developed by CNNMoney to measure the primary emotions (fear and greed) that influence how much investors are willing to pay for stocks.',
link: 'https://money.cnn.com/data/fear-and-greed/'
},
{
title: 'Inflation Chart',
description:
'Inflation Chart helps you find the intrinsic value of stock markets, stock prices, goods and services by adjusting them to the amount of the money supply (M0, M1, M2) or price of other goods (food or oil).',
link: 'https://inflationchart.com'
},
{
title: 'Stock Heatmap',
description:
'With the Stock Heatmap you can track the daily market movements of stocks as a visual snapshot.',
link: 'https://www.tradingview.com/heatmap/stock'
}
];
}

11
apps/client/src/app/pages/resources/markets/resources-markets.module.ts

@ -0,0 +1,11 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ResourcesMarketsRoutingModule } from './resources-markets-routing.module';
import { ResourcesMarketsComponent } from './resources-markets.component';
@NgModule({
declarations: [ResourcesMarketsComponent],
imports: [CommonModule, ResourcesMarketsRoutingModule]
})
export class ResourcesMarketsModule {}

17
apps/client/src/app/pages/resources/overview/resources-overview-routing.module.ts

@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ResourcesOverviewComponent } from './resources-overview.component';
const routes: Routes = [
{
path: '',
component: ResourcesOverviewComponent
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ResourcesOverviewRoutingModule {}

16
apps/client/src/app/pages/resources/overview/resources-overview.component.html

@ -0,0 +1,16 @@
<div class="container">
<div class="row">
<div class="col">
<h1 class="h3 mb-4 text-center" i18n>Resources Overview</h1>
<div class="overview-list">
@for (item of overviewItems; track item) {
<div class="mb-4">
<h3 class="h5 mt-0">{{ item.title }}</h3>
<p class="mb-1">{{ item.description }}</p>
<a [routerLink]="item.link">Explore →</a>
</div>
}
</div>
</div>
</div>
</div>

43
apps/client/src/app/pages/resources/overview/resources-overview.component.scss

@ -0,0 +1,43 @@
:host {
display: block;
color: rgb(var(--dark-primary-text));
}
.container {
max-width: 800px;
margin: 0 auto;
}
h1 {
margin-bottom: 2rem;
}
.overview-list {
.mb-4 {
margin-bottom: 2rem;
}
h3 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-bottom: 0.5rem;
}
a {
color: rgba(var(--palette-primary-500), 1);
font-weight: 500;
text-decoration: none;
&:hover {
color: rgba(var(--palette-primary-300), 1);
text-decoration: underline;
}
}
}
:host-context(.theme-dark) {
color: rgb(var(--light-primary-text));
}

35
apps/client/src/app/pages/resources/overview/resources-overview.component.ts

@ -0,0 +1,35 @@
import { Component } from '@angular/core';
@Component({
selector: 'gf-resources-overview',
templateUrl: './resources-overview.component.html',
styleUrls: ['./resources-overview.component.scss']
})
export class ResourcesOverviewComponent {
public overviewItems = [
{
title: 'Frequently Asked Questions (FAQ)',
description:
'Find quick answers to commonly asked questions about Ghostfolio in our Frequently Asked Questions (FAQ) section.',
link: '/faq'
},
{
title: 'Guides',
description:
'Explore our guides to help you get started with investing and managing your finances.',
link: '/resources/guides'
},
{
title: 'Markets',
description:
'Access various market resources and tools to stay informed about financial markets.',
link: '/resources/markets'
},
{
title: 'Glossary',
description:
'Learn key financial terms and concepts in our comprehensive glossary.',
link: '/resources/glossary'
}
];
}

12
apps/client/src/app/pages/resources/overview/resources-overview.module.ts

@ -0,0 +1,12 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { ResourcesOverviewRoutingModule } from './resources-overview-routing.module';
import { ResourcesOverviewComponent } from './resources-overview.component';
@NgModule({
declarations: [ResourcesOverviewComponent],
imports: [CommonModule, RouterModule, ResourcesOverviewRoutingModule]
})
export class ResourcesOverviewModule {}

44
apps/client/src/app/pages/resources/resources-page-routing.module.ts

@ -3,22 +3,48 @@ import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
// import { ResourcesGlossaryPageComponent } from './glossary/resources-glossary.component';
// import { ResourcesGuidesComponent } from './guides/resources-guides.component';
// import { ResourcesMarketsComponent } from './markets/resources-markets.component';
// import { ResourcesOverviewComponent } from './overview/resources-overview.component';
import { ResourcesPageComponent } from './resources-page.component';
const routes: Routes = [
{
canActivate: [AuthGuard],
component: ResourcesPageComponent,
path: '',
title: $localize`Resources`
component: ResourcesPageComponent,
canActivate: [AuthGuard],
children: [
{
path: 'guides',
loadChildren: () =>
import('./guides/resources-guides.module').then(
(m) => m.ResourcesGuidesModule
)
},
{
path: 'markets',
loadChildren: () =>
import('./markets/resources-markets.module').then(
(m) => m.ResourcesMarketsModule
)
},
...['personal-finance-tools'].map((path) => ({
path,
{
path: 'glossary',
loadChildren: () =>
import('./glossary/resources-glossary.module').then(
(m) => m.ResourcesGlossaryPageModule
)
},
{
path: '',
loadChildren: () =>
import(
'./personal-finance-tools/personal-finance-tools-page.module'
).then((m) => m.PersonalFinanceToolsPageModule)
}))
import('./overview/resources-overview.module').then(
(m) => m.ResourcesOverviewModule
)
}
]
}
];
@NgModule({

20
apps/client/src/app/pages/resources/resources-page.component.ts

@ -6,10 +6,10 @@ import { Component, OnInit } from '@angular/core';
import { Subject } from 'rxjs';
@Component({
host: { class: 'page' },
host: { class: 'page has-tabs' },
selector: 'gf-resources-page',
styleUrls: ['./resources-page.scss'],
templateUrl: './resources-page.html'
templateUrl: './resources-page.html',
styleUrls: ['./resources-page.scss']
})
export class ResourcesPageComponent implements OnInit {
public hasPermissionForSubscription: boolean;
@ -19,6 +19,20 @@ export class ResourcesPageComponent implements OnInit {
'/' + $localize`:snake-case:resources`,
'personal-finance-tools'
];
public tabs = [
{
path: '.',
label: $localize`Overview`,
iconName: 'information-circle-outline'
},
{ path: 'guides', label: $localize`Guides`, iconName: 'book-outline' },
{
path: 'markets',
label: $localize`Markets`,
iconName: 'trending-up-outline'
},
{ path: 'glossary', label: $localize`Glossary`, iconName: 'list-outline' }
];
private unsubscribeSubject = new Subject<void>();

286
apps/client/src/app/pages/resources/resources-page.html

@ -1,258 +1,30 @@
<div class="container">
<div class="row">
<div class="col">
<h1 class="d-none d-sm-block h3 mb-4 text-center" i18n>Resources</h1>
<h2 class="h4 mb-3">Ghostfolio</h2>
<div class="mb-5">
<div class="mb-4 media">
<div class="media-body">
<h3 class="h5 mt-0">Frequently Asked Questions (FAQ)</h3>
<div class="mb-1">
Find quick answers to commonly asked questions about Ghostfolio in
our Frequently Asked Questions (FAQ) section.
</div>
<div>
<a [routerLink]="routerLinkFaq"
>Frequently Asked Questions (FAQ) →</a
>
</div>
</div>
</div>
</div>
<h2 class="h4 mb-3" i18n>Guides</h2>
<div class="mb-5">
<div class="mb-4 media">
<div class="media-body">
<h3 class="h5 mt-0">Boringly Getting Rich</h3>
<div class="mb-1">
The <i>Boringly Getting Rich</i> guide supports you to get started
with investing. It introduces a strategy utilizing a broadly
diversified, low-cost portfolio excluding the risks of individual
stocks.
</div>
<div>
<a href="https://herget.me/investing-guide" target="_blank"
>Boringly Getting Rich →</a
>
</div>
</div>
</div>
<div class="mb-4 media">
<div class="media-body">
<h3 class="h5 mt-0">How do I get my finances in order?</h3>
<div class="mb-1">
Before you can think of long-term investing, you have to get your
finances in order. Learn how you can reach your financial goals
easier and faster in this guide.
</div>
<div>
<a href="../en/blog/2022/07/how-do-i-get-my-finances-in-order"
>How do I get my finances in order? →</a
>
</div>
</div>
</div>
</div>
<h2 class="h4 mb-3" i18n>Markets</h2>
<div class="mb-5">
<div class="mb-4 media">
<div class="media-body">
<h3 class="h5 mt-0">Crypto Coins Heatmap</h3>
<div class="mb-1">
With the <i>Crypto Coins Heatmap</i> you can track the daily
market movements of cryptocurrencies as a visual snapshot.
</div>
<div>
<a
href="https://www.tradingview.com/heatmap/crypto"
target="_blank"
>Crypto Coins Heatmap →</a
>
</div>
</div>
</div>
<div class="mb-4 media">
<div class="media-body">
<h3 class="h5 mt-0">Fear & Greed Index</h3>
<div class="mb-1">
The fear and greed index was developed by <i>CNNMoney</i> to
measure the primary emotions (fear and greed) that influence how
much investors are willing to pay for stocks.
</div>
<div>
<a
href="https://money.cnn.com/data/fear-and-greed/"
target="_blank"
>Fear & Greed Index →</a
>
</div>
</div>
</div>
<div class="media">
<div class="mb-4 media">
<h3 class="h5 mt-0">Inflation Chart</h3>
<div class="mb-1">
<i>Inflation Chart</i> helps you find the intrinsic value of stock
markets, stock prices, goods and services by adjusting them to the
amount of the money supply (M0, M1, M2) or price of other goods
(food or oil).
</div>
<div>
<a href="https://inflationchart.com" target="_blank"
>Inflation Chart →</a
>
</div>
</div>
</div>
<div class="media">
<div class="media-body">
<h3 class="h5 mt-0">Stock Heatmap</h3>
<div class="mb-1">
With the <i>Stock Heatmap</i> you can track the daily market
movements of stocks as a visual snapshot.
</div>
<div>
<a
href="https://www.tradingview.com/heatmap/stock"
target="_blank"
>Stock Heatmap →</a
>
</div>
</div>
</div>
</div>
<h2 class="h4 mb-3" i18n>Glossary</h2>
<div>
<div class="mb-4 media">
<div class="media-body">
<h3 class="h5 mt-0">Buy and Hold</h3>
<div class="mb-1">
Buy and hold is a passive investment strategy where you buy assets
and hold them for a long period regardless of fluctuations in the
market.
</div>
<div>
<a
href="https://www.investopedia.com/terms/b/buyandhold.asp"
target="_blank"
>Buy and Hold →</a
>
</div>
</div>
</div>
<div class="mb-4 media">
<div class="media-body">
<h3 class="h5 mt-0">Deflation</h3>
<div class="mb-1">
Deflation is a decrease of the general price level for goods and
services in an economy over a period of time.
</div>
<div>
<a
href="https://www.investopedia.com/terms/d/deflation.asp"
target="_blank"
>Deflation →</a
>
</div>
</div>
</div>
<div class="mb-4 media">
<div class="media-body">
<h3 class="h5 mt-0">Dollar-Cost Averaging (DCA)</h3>
<div class="mb-1">
Dollar-cost averaging is an investment strategy where you split
the total amount to be invested across periodic purchases of a
target asset to reduce the impact of volatility on the overall
purchase.
</div>
<div>
<a
href="https://www.investopedia.com/terms/d/dollarcostaveraging.asp"
target="_blank"
>Dollar-Cost Averaging →</a
>
</div>
</div>
</div>
<div class="mb-4 media">
<div class="media-body">
<h3 class="h5 mt-0">Financial Independence</h3>
<div class="mb-1">
Financial independence is the status of having enough income, for
example with a passive income like dividends, to cover your living
expenses for the rest of your life.
</div>
<div>
<a
href="https://en.wikipedia.org/wiki/Financial_independence"
target="_blank"
>Financial Independence →</a
>
</div>
</div>
</div>
<div class="mb-4 media">
<div class="media-body">
<h3 class="h5 mt-0">FIRE</h3>
<div class="mb-1">
FIRE is a movement that promotes saving and investing to achieve
financial independence and early retirement.
</div>
<div>
<a href="../en/blog/2023/07/exploring-the-path-to-fire">FIRE →</a>
</div>
</div>
</div>
<div class="mb-4 media">
<div class="media-body">
<h3 class="h5 mt-0">Inflation</h3>
<div class="mb-1">
Inflation is an increase of the general price level for goods and
services in an economy over a period of time.
</div>
<div>
<a
href="https://www.investopedia.com/terms/i/inflation.asp"
target="_blank"
>Inflation →</a
>
</div>
</div>
</div>
@if (hasPermissionForSubscription) {
<div class="mb-4 media">
<div class="media-body">
<h3 class="h5 mt-0">Personal Finance Tools</h3>
<div class="mb-1">
Personal finance tools are software applications that help
individuals manage their money, track expenses, set budgets,
monitor investments, and make informed financial decisions.
</div>
<div>
<a [routerLink]="routerLinkResourcesPersonalFinanceTools"
>Personal Finance Tools →</a
>
</div>
</div>
</div>
<mat-tab-nav-panel #tabPanel class="flex-grow-1 overflow-auto">
<router-outlet></router-outlet>
</mat-tab-nav-panel>
<nav
mat-align-tabs="center"
mat-tab-nav-bar
[disablePagination]="true"
[tabPanel]="tabPanel"
>
@for (tab of tabs; track tab) {
@if (tab.showCondition !== false) {
<a
#rla="routerLinkActive"
class="no-min-width px-3"
mat-tab-link
routerLinkActive
[active]="rla.isActive"
[routerLink]="tab.path"
[routerLinkActiveOptions]="{ exact: true }"
>
<ion-icon
[name]="tab.iconName"
[size]="deviceType === 'mobile' ? 'large' : 'small'"
/>
<div class="d-none d-sm-block ml-2">{{ tab.label }}</div>
</a>
}
<div class="mb-4 media">
<div class="media-body">
<h3 class="h5 mt-0">Stagflation</h3>
<div class="mb-1">
Stagflation describes a situation in which there is a stagnant
economy with high unemployment and high inflation.
</div>
<div>
<a
href="https://www.investopedia.com/terms/s/stagflation.asp"
target="_blank"
>Stagflation →</a
>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
}
</nav>

9
apps/client/src/app/pages/resources/resources-page.module.ts

@ -1,12 +1,19 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatTabsModule } from '@angular/material/tabs';
import { RouterModule } from '@angular/router';
import { ResourcesPageRoutingModule } from './resources-page-routing.module';
import { ResourcesPageComponent } from './resources-page.component';
@NgModule({
declarations: [ResourcesPageComponent],
imports: [CommonModule, ResourcesPageRoutingModule],
imports: [
CommonModule,
ResourcesPageRoutingModule,
MatTabsModule,
RouterModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class ResourcesPageModule {}

62
apps/client/src/app/pages/resources/resources-page.scss

@ -1,6 +1,13 @@
:host {
color: rgb(var(--dark-primary-text));
display: block;
display: flex;
flex-direction: row;
height: 100%;
// Add this to ensure proper ordering
nav {
order: 1; // This will force the nav to be first
}
a {
color: rgba(var(--palette-primary-500), 1);
@ -15,3 +22,56 @@
:host-context(.theme-dark) {
color: rgb(var(--light-primary-text));
}
.mat-tab-nav-bar {
border-top: none;
border-right: 1px solid rgba(0, 0, 0, 0.12);
flex-direction: column;
width: 240px;
}
.mat-tab-link {
flex-direction: row;
justify-content: flex-start;
height: 48px;
padding: 0 16px;
min-width: auto;
ion-icon {
font-size: 24px;
}
.d-none {
margin-left: 8px;
}
}
@media (max-width: 599px) {
:host {
flex-direction: column-reverse;
}
.mat-tab-nav-bar {
width: 100%;
border-right: none;
border-top: 1px solid rgba(0, 0, 0, 0.12);
}
.mat-tab-link {
flex-direction: column;
height: auto;
padding: 8px 16px;
ion-icon {
font-size: 28px;
}
}
}
.flex-grow-1 {
flex-grow: 1;
}
.overflow-auto {
overflow: auto;
}

31
package-lock.json

@ -29,6 +29,7 @@
"@dfinity/principal": "0.15.7",
"@dinero.js/currencies": "2.0.0-alpha.8",
"@internationalized/number": "3.5.2",
"@ionic/angular": "^8.3.2",
"@nestjs/bull": "10.0.1",
"@nestjs/cache-manager": "2.2.2",
"@nestjs/common": "10.1.3",
@ -4261,6 +4262,36 @@
"@swc/helpers": "^0.5.0"
}
},
"node_modules/@ionic/angular": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-8.3.2.tgz",
"integrity": "sha512-mbQgWWOzOHdzYEuixJNl2HJ+QUPAakvaG2D/oh7E+gvmA732ppnpHWF8XR35bpIfQJeBby6/mNZN0Bp9RWAkWw==",
"license": "MIT",
"dependencies": {
"@ionic/core": "8.3.2",
"ionicons": "^7.0.0",
"jsonc-parser": "^3.0.0",
"tslib": "^2.3.0"
},
"peerDependencies": {
"@angular/core": ">=16.0.0",
"@angular/forms": ">=16.0.0",
"@angular/router": ">=16.0.0",
"rxjs": ">=7.5.0",
"zone.js": ">=0.13.0"
}
},
"node_modules/@ionic/core": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.3.2.tgz",
"integrity": "sha512-ptiDXnn4131eKpY862lv7c9xxjly7vi4O+WWCES78E+hXHvTEAundcA5F8eQyb0MFIFvCnOxreTZjRJJnHqPYw==",
"license": "MIT",
"dependencies": {
"@stencil/core": "4.20.0",
"ionicons": "^7.2.2",
"tslib": "^2.1.0"
}
},
"node_modules/@ioredis/commands": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz",

1
package.json

@ -75,6 +75,7 @@
"@dfinity/principal": "0.15.7",
"@dinero.js/currencies": "2.0.0-alpha.8",
"@internationalized/number": "3.5.2",
"@ionic/angular": "^8.3.2",
"@nestjs/bull": "10.0.1",
"@nestjs/cache-manager": "2.2.2",
"@nestjs/common": "10.1.3",

Loading…
Cancel
Save