From 17e74a18a35e6940e537ea47f74d9bbb2d933b9c Mon Sep 17 00:00:00 2001 From: Solomon Laing Date: Mon, 26 Apr 2021 20:05:45 +0930 Subject: [PATCH] got basic implementation of project cards and the suppporting services/routing working. need to style project page now and will have first pass done --- src/app/app-routing.module.ts | 2 + src/app/app.module.ts | 4 +- src/app/page404/page404.component.html | 2 + src/app/page404/page404.component.scss | 5 +++ src/app/page404/page404.component.spec.ts | 25 +++++++++++ src/app/page404/page404.component.ts | 15 +++++++ .../project-card/project-card.component.html | 5 ++- .../project-card/project-card.component.scss | 22 ++++++++++ .../project-card/project-card.component.ts | 6 ++- .../projects/project/project.component.html | 1 + src/app/projects/project/project.component.ts | 43 +++++++++++++++++-- src/app/projects/projects.component.html | 5 ++- src/app/projects/projects.service.ts | 42 +++++++++++++++++- src/app/shared/models/pages.model.ts | 3 +- src/app/shared/models/project.model.ts | 1 + 15 files changed, 172 insertions(+), 9 deletions(-) create mode 100644 src/app/page404/page404.component.html create mode 100644 src/app/page404/page404.component.scss create mode 100644 src/app/page404/page404.component.spec.ts create mode 100644 src/app/page404/page404.component.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 63bd139..6001582 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -2,6 +2,7 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { LinksComponent } from './links/links.component'; +import { Page404Component } from './page404/page404.component'; import { PetComponent } from './pet/pet.component'; import { ProjectsComponent } from './projects/projects.component'; import { Pages } from './shared/models/pages.model'; @@ -12,6 +13,7 @@ const routes: Routes = [ // { path: AppRoutes.CORE, loadChildren: () => import('./galler/gallery.module').then((m) => m.GalleryModule) }, // for future use maybe { path: Pages.LINKS, component: LinksComponent }, { path: Pages.PET, component: PetComponent }, + { path: Pages.PAGE_404, component: Page404Component }, { path: '**', redirectTo: Pages.HOME, pathMatch: 'full' }]; @NgModule({ diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ab0f8ae..1464527 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -11,6 +11,7 @@ import { HomeComponent } from './home/home.component'; import { LinksComponent } from './links/links.component'; import { PetComponent } from './pet/pet.component'; import { HttpClientModule } from '@angular/common/http'; +import { Page404Component } from './page404/page404.component'; @NgModule({ declarations: [ @@ -20,7 +21,8 @@ import { HttpClientModule } from '@angular/common/http'; FooterComponent, HomeComponent, LinksComponent, - PetComponent + PetComponent, + Page404Component ], imports: [ SharedModule, diff --git a/src/app/page404/page404.component.html b/src/app/page404/page404.component.html new file mode 100644 index 0000000..e5abac8 --- /dev/null +++ b/src/app/page404/page404.component.html @@ -0,0 +1,2 @@ +

Page Not Found?

+

Sorry.

\ No newline at end of file diff --git a/src/app/page404/page404.component.scss b/src/app/page404/page404.component.scss new file mode 100644 index 0000000..e026e1c --- /dev/null +++ b/src/app/page404/page404.component.scss @@ -0,0 +1,5 @@ +:host { + display: flex; + flex-direction: column; + text-align: center; +} \ No newline at end of file diff --git a/src/app/page404/page404.component.spec.ts b/src/app/page404/page404.component.spec.ts new file mode 100644 index 0000000..38b4072 --- /dev/null +++ b/src/app/page404/page404.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Page404Component } from './page404.component'; + +describe('Page404Component', () => { + let component: Page404Component; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ Page404Component ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(Page404Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/page404/page404.component.ts b/src/app/page404/page404.component.ts new file mode 100644 index 0000000..ca07c7a --- /dev/null +++ b/src/app/page404/page404.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-page404', + templateUrl: './page404.component.html', + styleUrls: ['./page404.component.scss'] +}) +export class Page404Component implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/projects/project-card/project-card.component.html b/src/app/projects/project-card/project-card.component.html index 98ff4ff..6cc1921 100644 --- a/src/app/projects/project-card/project-card.component.html +++ b/src/app/projects/project-card/project-card.component.html @@ -1 +1,4 @@ -

project-card works!

+ +

{{project.title}}

+

{{project.description}}

+
\ No newline at end of file diff --git a/src/app/projects/project-card/project-card.component.scss b/src/app/projects/project-card/project-card.component.scss index e69de29..d902910 100644 --- a/src/app/projects/project-card/project-card.component.scss +++ b/src/app/projects/project-card/project-card.component.scss @@ -0,0 +1,22 @@ +@use 'src/app/shared/styles/_variables.color' as colors; + +:host { + flex-direction: column; + display: flex; + background-color: colors.$inklets-color-bg; + margin-bottom: 20px; + + a { + color: colors.$inklets-color-white; + border: colors.$inklets-color-highlight-bg 2px dashed; + background-color: colors.$inklets-color-fg; + text-decoration: none; + padding: 0 20px 0 20px; + } + + a:hover { + background-color: colors.$inklets-color-highlight-fg; + color: colors.$inklets-color-black; + } + +} \ No newline at end of file diff --git a/src/app/projects/project-card/project-card.component.ts b/src/app/projects/project-card/project-card.component.ts index 06ce8d9..fcc7491 100644 --- a/src/app/projects/project-card/project-card.component.ts +++ b/src/app/projects/project-card/project-card.component.ts @@ -1,4 +1,5 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; +import { Project } from 'src/app/shared/models/project.model'; @Component({ selector: 'app-project-card', @@ -7,6 +8,9 @@ import { Component, OnInit } from '@angular/core'; }) export class ProjectCardComponent implements OnInit { + @Input() + project: Project; + constructor() { } ngOnInit(): void { diff --git a/src/app/projects/project/project.component.html b/src/app/projects/project/project.component.html index 8ea00ea..dc66179 100644 --- a/src/app/projects/project/project.component.html +++ b/src/app/projects/project/project.component.html @@ -1 +1,2 @@

project works!

+{{project.title}} diff --git a/src/app/projects/project/project.component.ts b/src/app/projects/project/project.component.ts index e4e21ec..ce93a3e 100644 --- a/src/app/projects/project/project.component.ts +++ b/src/app/projects/project/project.component.ts @@ -1,15 +1,52 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { Project } from 'src/app/shared/models/project.model'; +import { ProjectsService } from '../projects.service'; @Component({ selector: 'app-project', templateUrl: './project.component.html', styleUrls: ['./project.component.scss'] }) -export class ProjectComponent implements OnInit { +export class ProjectComponent implements OnInit, OnDestroy { + _unsubscribe$: Subject = new Subject(); - constructor() { } + project: Project = { + title: '', + description: '', + slug: '', + ct: '', + body: '', + }; + + constructor( + private route: ActivatedRoute, + private projectsService: ProjectsService + ) { } ngOnInit(): void { + let id: string; + this.route.paramMap.subscribe((params) => { + id = params.get('id'); + }); + + this.projectsService.getProject(id); + + this.projectsService.currentProject$ + .pipe(takeUntil(this._unsubscribe$)) + .subscribe((result: Project) => { + if (!!result) { + this.project = result; + } + }); + + } + + ngOnDestroy(): void { + this._unsubscribe$.next(false); + this._unsubscribe$.complete(); } } diff --git a/src/app/projects/projects.component.html b/src/app/projects/projects.component.html index b8607a9..4a04f43 100644 --- a/src/app/projects/projects.component.html +++ b/src/app/projects/projects.component.html @@ -2,4 +2,7 @@

These are my projects as can be found on my gitlab. Mainly my programming projects that are quality enough for me to be happy for the world to see them. There are more in the works but they are currently private.

Projects of a personal nature

-

This is (will be) a summary of my personal projects be they my homelab, general electronics projects, or anything else.

\ No newline at end of file +

This is (will be) a summary of my personal projects be they my homelab, general electronics projects, or anything else.

+ + + \ No newline at end of file diff --git a/src/app/projects/projects.service.ts b/src/app/projects/projects.service.ts index a0e5e72..fa29dfb 100644 --- a/src/app/projects/projects.service.ts +++ b/src/app/projects/projects.service.ts @@ -1,5 +1,6 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; +import { Router } from '@angular/router'; import { BehaviorSubject } from 'rxjs'; import { Project } from '../shared/models/project.model'; @@ -18,6 +19,16 @@ export class ProjectsService { return this._allProjects.getValue(); } + private _currentProject = new BehaviorSubject(null); + readonly currentProject$ = this._currentProject.asObservable(); + + private set currentProject(project: Project) { + this._currentProject.next(project); + } + private get currentProject(): Project { + return this._currentProject.getValue(); + } + private _apiErrored = new BehaviorSubject(false); readonly apiErrored$ = this._apiErrored.asObservable(); @@ -34,7 +45,7 @@ export class ProjectsService { private PROJECT_API_URL = "https://cms.inkletblot.com/api/json" - constructor(private http: HttpClient) { } + constructor(private http: HttpClient, private router: Router) { } httpOptions = { headers: new HttpHeaders({ @@ -50,11 +61,13 @@ export class ProjectsService { if (response) { // using text/plain so as to not get the preflight options request // as such : Project[] does not work as expected and objects must be parsed. + this.allProjects = [] for (let project of response) { this.allProjects.push({ title : project.title, description : project.description, ct : project.ct, + slug : this.generateSlug(project.title), body : project.body }); } @@ -66,4 +79,31 @@ export class ProjectsService { } ); } + + /** + * This is not very efficient code but I'm not planning on having that many projects and (if this turns into a blog) blog posts + * If this does become a general blog, then I will make this a bit more efficient. + * @param id slug of project to get + */ + getProject(id: string): void { + let found = false; + this.allProjects.forEach((project) => { + if (project.slug === id) { + found = true; + this.currentProject = project; + } + }) + if (!found) { + this.router.navigate(['not-found']) + } + } + + /** + * Currently this is very basic and assumes that generated slug will be unique, it may be updated in future. + * @param input string to use for generating the slug + * @returns a slug representation of the input string + */ + generateSlug(input: string): string { + return input.toLocaleLowerCase().split(" ").join("-"); + } } diff --git a/src/app/shared/models/pages.model.ts b/src/app/shared/models/pages.model.ts index da77482..0619761 100644 --- a/src/app/shared/models/pages.model.ts +++ b/src/app/shared/models/pages.model.ts @@ -6,5 +6,6 @@ export enum Pages { PROJECTS = 'projects', GALLERY = 'gallery', LINKS = 'links', - PET = 'pet' + PET = 'pet', + PAGE_404 = 'not-found' } \ No newline at end of file diff --git a/src/app/shared/models/project.model.ts b/src/app/shared/models/project.model.ts index f5b9aab..28dec90 100644 --- a/src/app/shared/models/project.model.ts +++ b/src/app/shared/models/project.model.ts @@ -2,5 +2,6 @@ export interface Project { title: string, description: string, ct: string, + slug: string, body: string } \ No newline at end of file