Feature/add blog (#218)

* Setup blog

* Add german blog post

* Add english blog post

* Update changelog
pull/238/head
Thomas 3 years ago committed by GitHub
parent 61e667213e
commit 1c65599a16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added the date range component to the positions tab
- Added a blog
## 1.29.0 - 26.07.2021

@ -28,6 +28,10 @@ export class InfoService {
const globalPermissions: string[] = [];
if (this.configurationService.get('ENABLE_FEATURE_BLOG')) {
globalPermissions.push(permissions.enableBlog);
}
if (this.configurationService.get('ENABLE_FEATURE_IMPORT')) {
globalPermissions.push(permissions.enableImport);
}

@ -15,6 +15,7 @@ export class ConfigurationService {
ALPHA_VANTAGE_API_KEY: str({ default: '' }),
CACHE_TTL: num({ default: 1 }),
DATA_SOURCES: json({ default: JSON.stringify([DataSource.YAHOO]) }),
ENABLE_FEATURE_BLOG: bool({ default: false }),
ENABLE_FEATURE_CUSTOM_SYMBOLS: bool({ default: false }),
ENABLE_FEATURE_FEAR_AND_GREED_INDEX: bool({ default: false }),
ENABLE_FEATURE_IMPORT: bool({ default: !environment.production }),

@ -5,6 +5,7 @@ export interface Environment extends CleanedEnvAccessors {
ALPHA_VANTAGE_API_KEY: string;
CACHE_TTL: number;
DATA_SOURCES: string | string[]; // string is not correct, error in envalid?
ENABLE_FEATURE_BLOG: boolean;
ENABLE_FEATURE_CUSTOM_SYMBOLS: boolean;
ENABLE_FEATURE_FEAR_AND_GREED_INDEX: boolean;
ENABLE_FEATURE_IMPORT: boolean;

@ -33,6 +33,20 @@ const routes: Routes = [
loadChildren: () =>
import('./pages/auth/auth-page.module').then((m) => m.AuthPageModule)
},
{
path: 'de/blog/2021/07/hallo-ghostfolio',
loadChildren: () =>
import(
'./pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.module'
).then((m) => m.HalloGhostfolioPageModule)
},
{
path: 'en/blog/2021/07/hello-ghostfolio',
loadChildren: () =>
import(
'./pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.module'
).then((m) => m.HelloGhostfolioPageModule)
},
{
path: 'home',
loadChildren: () =>

@ -20,7 +20,7 @@
a {
color: rgba(var(--palette-primary-500), 1);
font-weight: bold;
font-weight: 500;
}
}
}

@ -16,6 +16,8 @@ import { UserService } from '../services/user/user.service';
export class AuthGuard implements CanActivate {
private static PUBLIC_PAGE_ROUTES = [
'/about',
'/de/blog',
'/en/blog',
'/pricing',
'/register',
'/resources'
@ -43,7 +45,11 @@ export class AuthGuard implements CanActivate {
if (route.queryParams?.utm_source) {
this.router.navigate(['/register']);
resolve(false);
} else if (AuthGuard.PUBLIC_PAGE_ROUTES.includes(state.url)) {
} else if (
AuthGuard.PUBLIC_PAGE_ROUTES.filter((publicPageRoute) =>
state.url.startsWith(publicPageRoute)
)?.length > 0
) {
resolve(true);
return EMPTY;
} else if (state.url !== '/start') {

@ -17,7 +17,9 @@ import { environment } from '../../../environments/environment';
})
export class AboutPageComponent implements OnDestroy, OnInit {
public baseCurrency = baseCurrency;
public hasPermissionForBlog: boolean;
public hasPermissionForStatistics: boolean;
public hasPermissionForSubscription: boolean;
public isLoggedIn: boolean;
public lastPublish = environment.lastPublish;
public statistics: Statistics;
@ -40,11 +42,22 @@ export class AboutPageComponent implements OnDestroy, OnInit {
*/
public ngOnInit() {
const { globalPermissions, statistics } = this.dataService.fetchInfo();
this.hasPermissionForBlog = hasPermission(
globalPermissions,
permissions.enableBlog
);
this.hasPermissionForStatistics = hasPermission(
globalPermissions,
permissions.enableStatistics
);
this.hasPermissionForSubscription = hasPermission(
globalPermissions,
permissions.enableSubscription
);
this.statistics = statistics;
this.userService.stateChanged

@ -2,7 +2,7 @@
<div class="mb-5 row">
<div class="col">
<h3 class="d-flex justify-content-center mb-3" i18n>About Ghostfolio</h3>
<mat-card>
<mat-card class="about-container">
<mat-card-content>
<p>
<strong>Ghostfolio</strong> is a lightweight wealth management
@ -56,7 +56,10 @@
<ion-icon name="logo-github" size="large"></ion-icon>
</a>
</p>
<div class="d-flex justify-content-center">
<div
*ngIf="hasPermissionForSubscription"
class="d-flex justify-content-center"
>
<div
class="independent-and-bootstrapped-logo mb-2"
title="Ghostfolio is an independent & bootstrapped business"
@ -101,6 +104,54 @@
</div>
</div>
<div *ngIf="hasPermissionForBlog" class="mb-5 row">
<div class="col">
<h3 class="mb-3 text-center" i18n>Blog</h3>
<mat-card class="blog-container">
<mat-card-content>
<div class="container p-0">
<div class="flex-nowrap mb-3 no-gutters row">
<a
class="d-flex w-100"
[routerLink]="['/en', 'blog', '2021', '07', 'hello-ghostfolio']"
>
<div class="flex-grow-1">
<div class="h6 m-0 text-truncate">Hello Ghostfolio</div>
<div class="d-flex text-muted">31.07.2021</div>
</div>
<div class="align-items-center d-flex">
<ion-icon
class="chevron text-muted"
name="chevron-forward-outline"
size="small"
></ion-icon>
</div>
</a>
</div>
<div class="flex-nowrap no-gutters row">
<a
class="d-flex w-100"
[routerLink]="['/de', 'blog', '2021', '07', 'hallo-ghostfolio']"
>
<div class="flex-grow-1">
<div class="h6 m-0 text-truncate">Hallo Ghostfolio</div>
<div class="d-flex text-muted">31.07.2021</div>
</div>
<div class="align-items-center d-flex">
<ion-icon
class="chevron text-muted"
name="chevron-forward-outline"
size="small"
></ion-icon>
</div>
</a>
</div>
</div>
</mat-card-content>
</mat-card>
</div>
</div>
<div class="mb-5 row">
<div class="col">
<h3 class="mb-3 text-center" i18n>Changelog</h3>

@ -7,6 +7,18 @@
}
.mat-card {
&.about-container,
&.changelog {
a {
color: rgba(var(--palette-primary-500), 1);
font-weight: 500;
&:hover {
color: rgba(var(--palette-primary-300), 1);
}
}
}
&.changelog {
::ng-deep {
markdown {
@ -30,15 +42,6 @@
}
}
a {
color: rgba(var(--palette-primary-500), 1);
font-weight: bold;
&:hover {
color: rgba(var(--palette-primary-300), 1);
}
}
.independent-and-bootstrapped-logo {
background-image: url('/assets/bootstrapped-dark.svg');
background-position: center;

@ -35,7 +35,7 @@ export class AccountPageComponent implements OnDestroy, OnInit {
public couponId: string;
public currencies: Currency[] = [];
public defaultDateFormat = DEFAULT_DATE_FORMAT;
public hasPermissionForSubscription;
public hasPermissionForSubscription: boolean;
public hasPermissionToUpdateViewMode: boolean;
public hasPermissionToUpdateUserSettings: boolean;
public price: number;

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

@ -0,0 +1,7 @@
import { Component } from '@angular/core';
@Component({
selector: 'gf-hallo-ghostfolio-page',
templateUrl: './hallo-ghostfolio-page.html'
})
export class HalloGhostfolioPageComponent {}

@ -0,0 +1,194 @@
<div class="blog container">
<div class="row">
<div class="col">
<article>
<div class="mb-4 text-center">
<h1 class="mb-1" i18n>Hallo Ghostfolio 👋</h1>
<div class="text-muted"><small>31.07.2021</small></div>
</div>
<section class="mb-4">
<p>
In diesem Artikel möchte ich mein neues Open Source Projekt näher
vorstellen: <a href="https://ghostfol.io">Ghostfolio</a>, eine
web-basierte Software für das Management der persönlichen Finanzen.
</p>
</section>
<section class="mb-4">
<h2 class="h4">Welches Problem löst Ghostfolio?</h2>
<p>
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
Investitionen in verschiedene Anlageklassen verteilt auf
unterschiedliche Plattformen. Deshalb suchte ich nach einer App, die
mein Portfolio ganzheitlich zusammenfasst. Bei meiner
Internetrecherche und Suche in App Stores habe ich mehrere Lösungen
ausprobiert, doch keine hat mich vollkommen überzeugt: Zu
kompliziert, zu überladen, nicht optimiert für Smartphones oder zu
wenig umfassend.
</p>
</section>
<section class="mb-4">
<h2 class="h4">Die Vision</h2>
<p>
Besonders wichtig ist mir, dass ich in Echtzeit die Übersicht über
mein gesamtes Vermögen erhalte. Bisher hatte ich nur einmal im Jahr,
beim Abschluss der Steuererklärung, die aufbereiteten Zahlen zur
Verfügung. Zum Gesamtbild gehören neben Cash auf dem Sparkonto auch
länderspezifische Besonderheiten wie beispielsweise die freiwillige
Altersvorsorge (Säule 3a) in der Schweiz.
</p>
<p>
In der Zwischenzeit habe ich mit vielen Kollegen gesprochen, die
schon länger investieren. Nicht wenige haben aus denselben
Überlegungen über die Zeit ein komplexes Spreadsheet angelegt. Ich
finde, dass dies im Jahr 2021 besser gehen muss.
</p>
<div class="container my-4">
<div class="row">
<div class="col-md-10 offset-md-1">
<blockquote class="blockquote m-0">
<p class="mb-0">
Ghostfolio zeigt das Gesamtbild des Vermögens, um
bestmögliche Anlage-Entscheidungen zu treffen.
</p>
</blockquote>
</div>
</div>
</div>
<p>
Ghostfolio soll eine simple Wealth Management Software sein. Diese
präsentiert jederzeit das aktuelle Vermögen und unterstützt bei
zukünftigen Investments. Sei es beim Rebalancing des Portfolios in
Anlageklassen (Aktien, Cryptocurrencies, ETFs, etc.) oder der
Finanzierung einer Wohnung, Ghostfolio bietet eine solide,
datengestützte Entscheidungshilfe.
</p>
<p>
Ich lege grossen Wert auf Datenschutz. Als
<a href="https://github.com/ghostfolio/ghostfolio"
>Open Source Software</a
>
(OSS) kann Ghostfolio vollständig anonym genutzt werden, ohne die
gierigen Blicke von Grossbanken oder Big Tech.
</p>
</section>
<section class="mb-4">
<h2 class="h4">Von der Idee zur Umsetzung</h2>
<p>
Vor diesem Hintergrund habe ich das ambitionierte Projekt gestartet
und in kleinen Schritten eine Software programmiert, die ich rasch
selbst nutzen konnte. Als Stack habe ich mich für moderne
Web-Technologien entschieden, die mich persönlich besonders
interessieren beziehungsweise die ich gerne erlernen und vertiefen
möchte. Dazu zählen <a href="https://www.docker.com">Docker</a>,
<a href="https://nx.dev">Nx</a> für das Management des Monorepos,
<a href="https://nestjs.com">NestJS</a> für das Backend und
<a href="https://www.postgresql.org">PostgreSQL</a> als Datenbank.
Der Code ist sowohl im Frontend als auch im Backend in
<a href="https://www.typescriptlang.org">TypeScript</a>
geschrieben.
</p>
<p>
Da ich bei einigen Kalkulationen an meine Grenzen gestossen bin,
habe ich mit verschiedenen Möglichkeiten auseinandergesetzt, um
Unterstützung zu bekommen. In der Hoffnung, dass andere Leute
ebenfalls von der Lösung profitieren und bei Interesse mit
Verbesserungen beitragen können, habe ich den bestehenden Code als
Open Source Software veröffentlicht. Schon nach kurzer Zeit haben
<a
href="https://github.com/ghostfolio/ghostfolio/graphs/contributors"
>andere Entwickler</a
>
mit tollen Erweiterungen an Ghostfolio mitgewirkt.
</p>
</section>
<section class="mb-4">
<h2 class="h4">Wie kann ich das Projekt unterstützen?</h2>
<p>
Bist du ebenfalls besessen von einer maximal diversifizierten
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 href="https://ghostfol.io/pricing">Ghostfolio Premium</a>
Subscription zur Finanzierung des Hostings, einem positiven Rating
im
<a
href="https://play.google.com/store/apps/details?id=ch.dotsilver.ghostfolio.twa"
>Google Play Store</a
>, einem Sternchen auf
<a href="https://github.com/ghostfolio/ghostfolio">GitHub</a>,
Feedback, Bug Reports, Feature Requests und natürlich Contributions!
</p>
<p>
Du erreichst mich per E-Mail unter
<a href="mailto:hi@ghostfol.io">hi@ghostfol.io</a> oder auf Twitter
<a href="https://twitter.com/ghostfolio_">@ghostfolio_</a>.
</p>
<p>
Ich freue mich, von dir zu hören.<br />
Thomas von Ghostfolio
</p>
</section>
<section class="my-5">
<ul class="list-inline">
<li class="h5">
<span class="badge badge-light font-weight-normal mr-2"
>Aktie</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Altersvorsorge</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Anlage</span
>
<span class="badge badge-light font-weight-normal mr-2">App</span>
<span class="badge badge-light font-weight-normal mr-2"
>Cryptocurrency</span
>
<span class="badge badge-light font-weight-normal mr-2">ETF</span>
<span class="badge badge-light font-weight-normal mr-2"
>Feedback</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Fintech</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Ghostfolio</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Investition</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Open Source</span
>
<span class="badge badge-light font-weight-normal mr-2">OSS</span>
<span class="badge badge-light font-weight-normal mr-2"
>Portfolio</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Software</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Strategie</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Trading</span
>
<span class="badge badge-light font-weight-normal mr-2"
>TypeScript</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Vermögen</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Wealth Management</span
>
</li>
</ul>
</section>
</article>
</div>
</div>
</div>

@ -0,0 +1,15 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { HalloGhostfolioPageRoutingModule } from './hallo-ghostfolio-page-routing.module';
import { HalloGhostfolioPageComponent } from './hallo-ghostfolio-page.component';
@NgModule({
declarations: [HalloGhostfolioPageComponent],
exports: [],
imports: [CommonModule, HalloGhostfolioPageRoutingModule, RouterModule],
providers: [],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class HalloGhostfolioPageModule {}

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

@ -0,0 +1,7 @@
import { Component } from '@angular/core';
@Component({
selector: 'gf-hello-ghostfolio-page',
templateUrl: './hello-ghostfolio-page.html'
})
export class HelloGhostfolioPageComponent {}

@ -0,0 +1,173 @@
<div class="blog container">
<div class="row">
<div class="col">
<article>
<div class="mb-4 text-center">
<h1 class="mb-1" i18n>Hello Ghostfolio 👋</h1>
<div class="text-muted"><small>31.07.2021</small></div>
</div>
<section class="mb-4">
<p>
In this article I would like to introduce my new open source project
in more detail: <a href="https://ghostfol.io">Ghostfolio</a>, a
web-based personal finance management software.
</p>
</section>
<section class="mb-4">
<h2 class="h4">What problem does Ghostfolio solve?</h2>
<p>
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
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
internet and in app stores, I have tried several solutions, but none
of them has convinced me completely: too complicated, too cluttered,
not optimized for smartphones or not comprehensive enough.
</p>
</section>
<section class="mb-4">
<h2 class="h4">The vision</h2>
<p>
It is particularly important to me that I get an overview of all my
assets in real time. Previously, I only had the prepared figures
available once a year, when I had completed my annual tax
declaration. In addition to the cash balance in the savings account,
the overall picture also includes country-specific traits such as
the voluntary pension plan (pillar 3a) in Switzerland.
</p>
<p>
In the meantime, I have talked to many colleagues who have been
investing for a longer time. Quite a few have created complex
spreadsheets from the same considerations. I think that should be
better in 2021.
</p>
<div class="container my-4">
<div class="row">
<div class="col-md-10 offset-md-1">
<blockquote class="blockquote m-0">
<p class="mb-0">
Ghostfolio presents the big picture of assets to make the
best possible investment decisions.
</p>
</blockquote>
</div>
</div>
</div>
<p>
Ghostfolio is supposed to be a simple wealth management software. It
presents the current assets at any time and supports the decision
making of future investments. Whether rebalancing the portfolio in
asset classes (stocks, cryptocurrencies, ETFs, etc.) or financing an
apartment, Ghostfolio offers solid, data-driven decision support.
</p>
<p>
As I value privacy, data protection is an integral part of
Ghostfolio. As
<a href="https://github.com/ghostfolio/ghostfolio"
>open source software</a
>
(OSS), Ghostfolio can be used completely anonymously, without the
greedy eyes of big banks or big tech.
</p>
</section>
<section class="mb-4">
<h2 class="h4">From idea to implementation</h2>
<p>
With this background I have started the ambitious project and
programmed with small steps a software that I could quickly use for
myself. As a stack, I chose modern web technologies that are
personally of particular interest or that I would like to learn and
deepen. These include <a href="https://www.docker.com">Docker</a>,
<a href="https://nx.dev">Nx</a> for the management of the monorepo,
<a href="https://nestjs.com">NestJS</a> for the backend and
<a href="https://www.postgresql.org">PostgreSQL</a> as a database.
The code of the frontend and backend is written in
<a href="https://www.typescriptlang.org">TypeScript</a>.
</p>
<p>
Since I have shortly reached my limits with some calculations, I
have looked into different possibilities to get valuable support.
Hoping that other people could also benefit from the solution and
contribute with improvements if interested, I have released the
existing code as open source software. Very soon, other
<a
href="https://github.com/ghostfolio/ghostfolio/graphs/contributors"
>developers</a
>
contributed to Ghostfolio with great enhancements.
</p>
</section>
<section class="mb-4">
<h2 class="h4">How can I support the project?</h2>
<p>
Are you also obsessed with a maximally diversified investment
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 href="https://ghostfol.io/pricing">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"
>Google Play Store</a
>, a star on
<a href="https://github.com/ghostfolio/ghostfolio">GitHub</a>,
feedback, bug reports, feature requests and of course contributions!
</p>
<p>
You can reach me by email at
<a href="mailto:hi@ghostfol.io">hi@ghostfol.io</a> or on Twitter
<a href="https://twitter.com/ghostfolio_">@ghostfolio_</a>.
</p>
<p>
I look forward to hearing from you.<br />
Thomas from Ghostfolio
</p>
</section>
<section class="my-5">
<ul class="list-inline">
<li class="h5">
<span class="badge badge-light font-weight-normal mr-2"
>Cryptocurrency</span
>
<span class="badge badge-light font-weight-normal mr-2">ETF</span>
<span class="badge badge-light font-weight-normal mr-2"
>Fintech</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Ghostfolio</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Investment</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Open Source</span
>
<span class="badge badge-light font-weight-normal mr-2">OSS</span>
<span class="badge badge-light font-weight-normal mr-2"
>Portfolio</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Software</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Stock</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Strategy</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Wealth</span
>
<span class="badge badge-light font-weight-normal mr-2"
>Wealth Management</span
>
</li>
</ul>
</section>
</article>
</div>
</div>
</div>

@ -0,0 +1,15 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { HelloGhostfolioPageRoutingModule } from './hello-ghostfolio-page-routing.module';
import { HelloGhostfolioPageComponent } from './hello-ghostfolio-page.component';
@NgModule({
declarations: [HelloGhostfolioPageComponent],
exports: [],
imports: [CommonModule, HelloGhostfolioPageRoutingModule, RouterModule],
providers: [],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class HelloGhostfolioPageModule {}

@ -4,7 +4,7 @@
a {
color: rgba(var(--palette-primary-500), 1);
font-weight: bold;
font-weight: 500;
&:hover {
color: rgba(var(--palette-primary-300), 1);

@ -5,7 +5,7 @@
.mat-card {
a {
color: rgba(var(--palette-primary-500), 1);
font-weight: bold;
font-weight: 500;
&:hover {
color: rgba(var(--palette-primary-300), 1);

@ -42,7 +42,7 @@
a {
color: rgba(var(--palette-primary-500), 1);
font-weight: bold;
font-weight: 500;
&:hover {
color: rgba(var(--palette-primary-300), 1);

@ -6,22 +6,30 @@
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
<loc>https://ghostfol.io</loc>
<lastmod>2021-06-03T00:00:00+00:00</lastmod>
<lastmod>2021-07-31T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/about</loc>
<lastmod>2021-06-03T00:00:00+00:00</lastmod>
<lastmod>2021-07-31T00:00:00+00:00</lastmod>
</url>
<url>
<url>
<loc>https://ghostfol.io/de/blog/2021/07/hallo-ghostfolio</loc>
<lastmod>2021-07-31T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/en/blog/2021/07/hello-ghostfolio</loc>
<lastmod>2021-07-31T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/pricing</loc>
<lastmod>2021-06-03T00:00:00+00:00</lastmod>
<lastmod>2021-07-31T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/register</loc>
<lastmod>2021-06-03T00:00:00+00:00</lastmod>
<lastmod>2021-07-31T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/resources</loc>
<lastmod>2021-06-03T00:00:00+00:00</lastmod>
<lastmod>2021-07-31T00:00:00+00:00</lastmod>
</url>
</urlset>

@ -28,6 +28,22 @@ body {
a {
color: var(--dark-primary-text);
&:hover {
color: unset;
text-decoration: none;
}
}
.blog {
a {
color: rgba(var(--palette-primary-500), 1);
font-weight: 500;
&:hover {
text-decoration: underline;
}
}
}
&.is-dark-theme {
@ -82,11 +98,6 @@ body {
}
}
a:hover {
color: unset;
text-decoration: none;
}
button:focus {
outline: 0;
}

@ -15,6 +15,7 @@ export const permissions = {
deleteOrder: 'deleteOrder',
deleteUser: 'deleteUser',
enableImport: 'enableImport',
enableBlog: 'enableBlog',
enableSocialLogin: 'enableSocialLogin',
enableStatistics: 'enableStatistics',
enableSubscription: 'enableSubscription',

Loading…
Cancel
Save