Skip to content

Commit

Permalink
Merge pull request #183 from valerymelou/feature/blog-home
Browse files Browse the repository at this point in the history
feat: add the blog home page
  • Loading branch information
valerymelou authored May 26, 2024
2 parents bdfb5dd + 5ecccc4 commit 8e9ba1b
Show file tree
Hide file tree
Showing 30 changed files with 430 additions and 29 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ Thumbs.db

.nx/cache
.angular
.env
19 changes: 19 additions & 0 deletions apps/website/plugins/env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const myOrgEnvRegex = /^VM_/i;

const envVarPlugin = {
name: 'env-var-plugin',
setup(build) {
const options = build.initialOptions;

const envVars = {};
for (const key in process.env) {
if (myOrgEnvRegex.test(key)) {
envVars[key] = process.env[key];
}
}

options.define['process.env'] = JSON.stringify(envVars);
},
};

module.exports = envVarPlugin;
7 changes: 4 additions & 3 deletions apps/website/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"tags": [],
"targets": {
"build": {
"executor": "@angular-devkit/build-angular:application",
"executor": "@nx/angular:application",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/apps/website",
Expand All @@ -18,7 +18,8 @@
"inlineStyleLanguage": "scss",
"assets": ["apps/website/src/favicon.ico", "apps/website/src/assets"],
"styles": ["apps/website/src/styles.scss"],
"scripts": []
"scripts": [],
"plugins": ["apps/website/plugins/env.js"]
},
"configurations": {
"production": {
Expand All @@ -45,7 +46,7 @@
"defaultConfiguration": "production"
},
"serve": {
"executor": "@angular-devkit/build-angular:dev-server",
"executor": "@nx/angular:dev-server",
"configurations": {
"production": {
"buildTarget": "website:build:production"
Expand Down
19 changes: 18 additions & 1 deletion apps/website/src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,24 @@ import { provideAnimations } from '@angular/platform-browser/animations';
import { provideRouter } from '@angular/router';

import { appRoutes } from './app.routes';
import {
CONTENTFUL_ACCESS_TOKEN,
CONTENTFUL_ENVIRONMENT,
CONTENTFUL_SPACE,
} from '@valerymelou/cms/contentful';

export const appConfig: ApplicationConfig = {
providers: [provideAnimations(), provideRouter(appRoutes)],
providers: [
provideAnimations(),
provideRouter(appRoutes),
{ provide: CONTENTFUL_SPACE, useValue: process.env.VM_CONTENTFUL_SPACE },
{
provide: CONTENTFUL_ACCESS_TOKEN,
useValue: process.env.VM_CONTENTFUL_ACCESS_TOKEN,
},
{
provide: CONTENTFUL_ENVIRONMENT,
useValue: process.env.VM_CONTENTFUL_ENVIRONMENT,
},
],
};
8 changes: 7 additions & 1 deletion apps/website/src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,16 @@ export const appRoutes: Route[] = [
path: 'projects',
loadComponent: () =>
import('@valerymelou/pages/projects').then(
(c) => c.ProjectsComponent
(c) => c.ProjectsComponent,
),
data: { animation: 'ProjectsPage' },
},
{
path: 'blog',
loadComponent: () =>
import('@valerymelou/blog/home').then((c) => c.BlogHomeComponent),
data: { animation: 'BlogHomePage' },
},
],
},
];
7 changes: 7 additions & 0 deletions apps/website/src/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
declare const process: {
env: {
VM_CONTENTFUL_SPACE: string;
VM_CONTENTFUL_ENVIRONMENT: string;
VM_CONTENTFUL_ACCESS_TOKEN: string;
};
};
2 changes: 1 addition & 1 deletion apps/website/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module.exports = {
dark: colors.slate[900],
secondary: {
dark: '#112240',
base: '#1e3a8a',
light: colors.slate[200],
},
accent: {
base: '#068477',
Expand Down
36 changes: 36 additions & 0 deletions libs/blog/feature-home/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"extends": ["../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts"],
"extends": [
"plugin:@nx/angular",
"plugin:@angular-eslint/template/process-inline-templates"
],
"rules": {
"@angular-eslint/directive-selector": [
"error",
{
"type": "attribute",
"prefix": "blog",
"style": "camelCase"
}
],
"@angular-eslint/component-selector": [
"error",
{
"type": "element",
"prefix": "blog",
"style": "kebab-case"
}
]
}
},
{
"files": ["*.html"],
"extends": ["plugin:@nx/angular-template"],
"rules": {}
}
]
}
7 changes: 7 additions & 0 deletions libs/blog/feature-home/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# feature-home

This library was generated with [Nx](https://nx.dev).

## Running unit tests

Run `nx test feature-home` to execute the unit tests.
22 changes: 22 additions & 0 deletions libs/blog/feature-home/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* eslint-disable */
export default {
displayName: 'feature-home',
preset: '../../../jest.preset.js',
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
coverageDirectory: '../../../coverage/libs/blog/feature-home',
transform: {
'^.+\\.(ts|mjs|js|html)$': [
'jest-preset-angular',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$',
},
],
},
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
snapshotSerializers: [
'jest-preset-angular/build/serializers/no-ng-attributes',
'jest-preset-angular/build/serializers/ng-snapshot',
'jest-preset-angular/build/serializers/html-comment',
],
};
20 changes: 20 additions & 0 deletions libs/blog/feature-home/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "feature-home",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/blog/feature-home/src",
"prefix": "blog",
"projectType": "library",
"tags": [],
"targets": {
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/blog/feature-home/jest.config.ts"
}
},
"lint": {
"executor": "@nx/eslint:lint"
}
}
}
1 change: 1 addition & 0 deletions libs/blog/feature-home/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './lib/blog-home.component';
63 changes: 63 additions & 0 deletions libs/blog/feature-home/src/lib/blog-home.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<div class="my-10">
<h1
class="mb-5 text-2xl font-bold leading-[3rem] text-black md:text-4xl dark:text-white"
>
Inside my head
</h1>
<h2 class="text-xl lg:max-w-2xl">
I talk about Django, Angular... Web Development in general and many other
topics. These are just a few of the things in my head.
</h2>

<div class="my-10 grid grid-cols-12 gap-5">
<div class="col-span-12 lg:col-span-8">
@if (articles$ | async; as articles) {
@for (article of articles.items; track article.slug) {
<a
[routerLink]="['/blog', article.slug]"
class="dark:bg-secondary-dark dark:hover:bg-secondary-dark hover:bg-secondary-light bg-secondary-light mb-5 flex flex-col rounded-md p-5 transition-all duration-300 ease-in-out"
>
<div class="flex items-start">
<h3 class="font-medium text-black dark:text-white">
{{ article.title }}
</h3>
<p class="ml-auto text-sm">
{{ article.createdAt | date: 'mediumDate' }}
</p>
</div>
<p class="mt-5">
{{ article.abstract }}
</p>
<div class="mt-5 flex space-x-4">
@for (tag of article.tags; track tag.id) {
<a
[routerLink]="['/blog', 'topic', tag.id]"
ui-link
class="text-sm"
>{{ tag.label }}</a
>
}
</div>
</a>
}
}
</div>
<div
class="dark:bg-secondary-dark bg-secondary-light col-span-12 flex flex-col self-start rounded-md p-4 lg:col-span-4"
>
<h3 class="mb-5 text-xl">Topics</h3>
@if (tags$ | async; as tags) {
<div>
@for (tag of tags.items; track tag.id) {
<a
[routerLink]="['/blog', 'topic', tag.id]"
class="mr-3 text-sm"
ui-link
>{{ tag.label }}</a
>
}
</div>
}
</div>
</div>
</div>
41 changes: 41 additions & 0 deletions libs/blog/feature-home/src/lib/blog-home.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BlogHomeComponent } from './blog-home.component';
import {
Article,
ArticleService,
TagService,
} from '@valerymelou/blob/data-access';
import { of } from 'rxjs';

describe('BlogHomeComponent', () => {
let component: BlogHomeComponent;
let fixture: ComponentFixture<BlogHomeComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [BlogHomeComponent],
providers: [
{
provide: ArticleService,
useValue: {
get: () => of({ data: [new Article(), new Article()] }),
},
},
{
provide: TagService,
useValue: {
getAll: () => of({ data: [{ label: 'Django', id: 'django' }] }),
},
},
],
}).compileComponents();

fixture = TestBed.createComponent(BlogHomeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
42 changes: 42 additions & 0 deletions libs/blog/feature-home/src/lib/blog-home.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Observable } from 'rxjs';

import {
Article,
ArticleService,
Results,
Tag,
TagService,
} from '@valerymelou/blob/data-access';
import { LinkComponent } from '@valerymelou/shared/ui';
import { RouterModule } from '@angular/router';

@Component({
selector: 'blog-blog-home',
standalone: true,
imports: [CommonModule, RouterModule, LinkComponent],
templateUrl: './blog-home.component.html',
})
export class BlogHomeComponent implements OnInit {
articles$!: Observable<Results<Article>>;
tags$!: Observable<Results<Tag>>;

ngOnInit(): void {
this.loadArticles();
this.loadTags();
}

constructor(
private articleService: ArticleService,
private tagService: TagService,
) {}

loadArticles(): void {
this.articles$ = this.articleService.get({});
}

loadTags(): void {
this.tags$ = this.tagService.getAll();
}
}
8 changes: 8 additions & 0 deletions libs/blog/feature-home/src/test-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// @ts-expect-error https://thymikee.github.io/jest-preset-angular/docs/getting-started/test-environment
globalThis.ngJest = {
testEnvironmentOptions: {
errorOnUnknownElements: true,
errorOnUnknownProperties: true,
},
};
import 'jest-preset-angular/setup-jest';
29 changes: 29 additions & 0 deletions libs/blog/feature-home/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"compilerOptions": {
"target": "es2022",
"useDefineForClassFields": false,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
],
"extends": "../../../tsconfig.base.json",
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}
Loading

0 comments on commit 8e9ba1b

Please sign in to comment.