From fbb00cdecc51178f7894472c093fd0c9c1d5d68f Mon Sep 17 00:00:00 2001 From: Solomon Laing Date: Sun, 18 Apr 2021 21:07:04 +0930 Subject: [PATCH 1/5] started implementation of projects page. currently need to work out cors --- src/app/app-routing.module.ts | 4 +- src/app/app.module.ts | 6 +- .../project-card/project-card.component.html | 1 + .../project-card/project-card.component.scss | 0 .../project-card.component.spec.ts | 25 ++++++++ .../project-card/project-card.component.ts | 15 +++++ .../projects/project/project.component.html | 1 + .../projects/project/project.component.scss | 0 .../project/project.component.spec.ts | 25 ++++++++ src/app/projects/project/project.component.ts | 15 +++++ src/app/projects/projects-routing.module.ts | 21 +++++++ src/app/projects/projects.component.html | 6 +- src/app/projects/projects.component.ts | 25 +++++++- src/app/projects/projects.module.ts | 16 +++++ src/app/projects/projects.service.spec.ts | 16 +++++ src/app/projects/projects.service.ts | 60 +++++++++++++++++++ src/app/shared/models/project.model.ts | 6 ++ 17 files changed, 233 insertions(+), 9 deletions(-) create mode 100644 src/app/projects/project-card/project-card.component.html create mode 100644 src/app/projects/project-card/project-card.component.scss create mode 100644 src/app/projects/project-card/project-card.component.spec.ts create mode 100644 src/app/projects/project-card/project-card.component.ts create mode 100644 src/app/projects/project/project.component.html create mode 100644 src/app/projects/project/project.component.scss create mode 100644 src/app/projects/project/project.component.spec.ts create mode 100644 src/app/projects/project/project.component.ts create mode 100644 src/app/projects/projects-routing.module.ts create mode 100644 src/app/projects/projects.module.ts create mode 100644 src/app/projects/projects.service.spec.ts create mode 100644 src/app/projects/projects.service.ts create mode 100644 src/app/shared/models/project.model.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 65dc93b..63bd139 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -8,8 +8,8 @@ import { Pages } from './shared/models/pages.model'; const routes: Routes = [ { path: Pages.HOME, component: HomeComponent }, - { path: Pages.PROJECTS, component: ProjectsComponent }, - // { path: AppRoutes.CORE, loadChildren: () => import('./galler/gallery.module').then((m) => m.GalleryModule) }, // for future use + { path: Pages.PROJECTS, loadChildren: () => import('./projects/projects.module').then((m) => m.ProjectsModule) }, + // { 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: '**', redirectTo: Pages.HOME, pathMatch: 'full' }]; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index dfadf08..ab0f8ae 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -9,8 +9,8 @@ import { FooterComponent } from './footer/footer.component'; import { SharedModule } from './shared/shared.module'; import { HomeComponent } from './home/home.component'; import { LinksComponent } from './links/links.component'; -import { ProjectsComponent } from './projects/projects.component'; import { PetComponent } from './pet/pet.component'; +import { HttpClientModule } from '@angular/common/http'; @NgModule({ declarations: [ @@ -20,13 +20,13 @@ import { PetComponent } from './pet/pet.component'; FooterComponent, HomeComponent, LinksComponent, - ProjectsComponent, PetComponent ], imports: [ SharedModule, BrowserModule, - AppRoutingModule + AppRoutingModule, + HttpClientModule ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/projects/project-card/project-card.component.html b/src/app/projects/project-card/project-card.component.html new file mode 100644 index 0000000..98ff4ff --- /dev/null +++ b/src/app/projects/project-card/project-card.component.html @@ -0,0 +1 @@ +

project-card works!

diff --git a/src/app/projects/project-card/project-card.component.scss b/src/app/projects/project-card/project-card.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/projects/project-card/project-card.component.spec.ts b/src/app/projects/project-card/project-card.component.spec.ts new file mode 100644 index 0000000..8815d7d --- /dev/null +++ b/src/app/projects/project-card/project-card.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ProjectCardComponent } from './project-card.component'; + +describe('ProjectCardComponent', () => { + let component: ProjectCardComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ProjectCardComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ProjectCardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/projects/project-card/project-card.component.ts b/src/app/projects/project-card/project-card.component.ts new file mode 100644 index 0000000..06ce8d9 --- /dev/null +++ b/src/app/projects/project-card/project-card.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-project-card', + templateUrl: './project-card.component.html', + styleUrls: ['./project-card.component.scss'] +}) +export class ProjectCardComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/projects/project/project.component.html b/src/app/projects/project/project.component.html new file mode 100644 index 0000000..8ea00ea --- /dev/null +++ b/src/app/projects/project/project.component.html @@ -0,0 +1 @@ +

project works!

diff --git a/src/app/projects/project/project.component.scss b/src/app/projects/project/project.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/projects/project/project.component.spec.ts b/src/app/projects/project/project.component.spec.ts new file mode 100644 index 0000000..e0f0d74 --- /dev/null +++ b/src/app/projects/project/project.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ProjectComponent } from './project.component'; + +describe('ProjectComponent', () => { + let component: ProjectComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ProjectComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ProjectComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/projects/project/project.component.ts b/src/app/projects/project/project.component.ts new file mode 100644 index 0000000..e4e21ec --- /dev/null +++ b/src/app/projects/project/project.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-project', + templateUrl: './project.component.html', + styleUrls: ['./project.component.scss'] +}) +export class ProjectComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/projects/projects-routing.module.ts b/src/app/projects/projects-routing.module.ts new file mode 100644 index 0000000..74cf277 --- /dev/null +++ b/src/app/projects/projects-routing.module.ts @@ -0,0 +1,21 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { ProjectComponent } from './project/project.component'; +import { ProjectsComponent } from './projects.component'; + +const routes: Routes = [ + { + path: '', + component: ProjectsComponent + }, + { + path: ':id', + component: ProjectComponent + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class ProjectsRoutingModule {} diff --git a/src/app/projects/projects.component.html b/src/app/projects/projects.component.html index 885859a..b8607a9 100644 --- a/src/app/projects/projects.component.html +++ b/src/app/projects/projects.component.html @@ -1 +1,5 @@ -

projects works!

+

Projects on git

+

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 diff --git a/src/app/projects/projects.component.ts b/src/app/projects/projects.component.ts index 1172d9c..17af914 100644 --- a/src/app/projects/projects.component.ts +++ b/src/app/projects/projects.component.ts @@ -1,18 +1,37 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Subject } from 'rxjs/internal/Subject'; +import { takeUntil } from 'rxjs/operators'; import { NavService } from '../nav/nav.service'; import { Pages } from '../shared/models/pages.model'; +import { Project } from '../shared/models/project.model'; +import { ProjectsService } from './projects.service'; @Component({ selector: 'app-projects', templateUrl: './projects.component.html', styleUrls: ['./projects.component.scss'] }) -export class ProjectsComponent implements OnInit { +export class ProjectsComponent implements OnInit, OnDestroy { + _unsubscribe$: Subject = new Subject(); - constructor(private navService:NavService) { } + uncategorizedProjects: Array; + + constructor(private navService: NavService, private projectsService: ProjectsService) { } ngOnInit(): void { this.navService.setPageTitle(Pages.PROJECTS); + + this.projectsService.allProjects$ + .pipe(takeUntil(this._unsubscribe$)) + .subscribe((result: Project[]) => { + this.uncategorizedProjects = result; + }); + this.projectsService.getInvoicesToApprove(); + } + + ngOnDestroy(): void { + this._unsubscribe$.next(false); + this._unsubscribe$.complete(); } } diff --git a/src/app/projects/projects.module.ts b/src/app/projects/projects.module.ts new file mode 100644 index 0000000..bd6f109 --- /dev/null +++ b/src/app/projects/projects.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ProjectCardComponent } from './project-card/project-card.component'; +import { ProjectComponent } from './project/project.component'; +import { ProjectsComponent } from './projects.component'; +import { ProjectsRoutingModule } from './projects-routing.module'; + +@NgModule({ + declarations: [ProjectsComponent, ProjectCardComponent, ProjectComponent], + imports: [ + CommonModule, + ProjectsRoutingModule + ], + providers: [] +}) +export class ProjectsModule { } diff --git a/src/app/projects/projects.service.spec.ts b/src/app/projects/projects.service.spec.ts new file mode 100644 index 0000000..96c6dcc --- /dev/null +++ b/src/app/projects/projects.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { ProjectsService } from './projects.service'; + +describe('ProjectsService', () => { + let service: ProjectsService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(ProjectsService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/projects/projects.service.ts b/src/app/projects/projects.service.ts new file mode 100644 index 0000000..384962d --- /dev/null +++ b/src/app/projects/projects.service.ts @@ -0,0 +1,60 @@ +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; +import { Project } from '../shared/models/project.model'; + +@Injectable({ + providedIn: 'root' +}) +export class ProjectsService { + + private _allProjects = new BehaviorSubject>([]); + readonly allProjects$ = this._allProjects.asObservable(); + + private set allProjects(projects: Array) { + this._allProjects.next(projects); + } + private get allProjects(): Array { + return this._allProjects.getValue(); + } + + private _apiErrored = new BehaviorSubject(false); + readonly apiErrored$ = this._apiErrored.asObservable(); + + private set apiErrored(errored: boolean) { + this._apiErrored.next(errored); + } + private get apiErrored(): boolean { + return this._apiErrored.getValue(); + } + + /** + * I am actively avoiding any kind of environment management, this is a very basic site and currently this is the only api call. + */ + + private PROJECT_API_URL = "https://cms.inkletblot.com/" + + constructor(private http: HttpClient) { } + + httpOptions = { + headers: new HttpHeaders({ + 'Content-Type': 'application/json' + }) + }; + + getInvoicesToApprove(): void { + this.http + .get(`${this.PROJECT_API_URL}`, this.httpOptions) + .subscribe( + (response: Project[]) => { + if (response) { + this.allProjects = response; + // filter out different categories here currently only one + } + }, + (error) => { + this.apiErrored = true; + } + ); + } +} diff --git a/src/app/shared/models/project.model.ts b/src/app/shared/models/project.model.ts new file mode 100644 index 0000000..f5b9aab --- /dev/null +++ b/src/app/shared/models/project.model.ts @@ -0,0 +1,6 @@ +export interface Project { + title: string, + description: string, + ct: string, + body: string +} \ No newline at end of file From 036f48b3f08ad9991e963d0101e13c2170bac69a Mon Sep 17 00:00:00 2001 From: Solomon Laing Date: Tue, 20 Apr 2021 19:30:30 +0930 Subject: [PATCH 2/5] Got api request working. I added the necessary header to the api server and then changed the content type of the request to text/plain to disabled the preflight OPTIONS request which the server was erroring on. Not sure about the security of all this but it's a very basic website and I don't think it'll be an issue. --- src/app/projects/projects.service.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/app/projects/projects.service.ts b/src/app/projects/projects.service.ts index 384962d..a0e5e72 100644 --- a/src/app/projects/projects.service.ts +++ b/src/app/projects/projects.service.ts @@ -32,13 +32,13 @@ export class ProjectsService { * I am actively avoiding any kind of environment management, this is a very basic site and currently this is the only api call. */ - private PROJECT_API_URL = "https://cms.inkletblot.com/" + private PROJECT_API_URL = "https://cms.inkletblot.com/api/json" constructor(private http: HttpClient) { } httpOptions = { headers: new HttpHeaders({ - 'Content-Type': 'application/json' + 'Content-Type': 'text/plain' }) }; @@ -48,7 +48,16 @@ export class ProjectsService { .subscribe( (response: Project[]) => { if (response) { - this.allProjects = 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. + for (let project of response) { + this.allProjects.push({ + title : project.title, + description : project.description, + ct : project.ct, + body : project.body + }); + } // filter out different categories here currently only one } }, From 17e74a18a35e6940e537ea47f74d9bbb2d933b9c Mon Sep 17 00:00:00 2001 From: Solomon Laing Date: Mon, 26 Apr 2021 20:05:45 +0930 Subject: [PATCH 3/5] 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 From 5d754396da0c4e79ced37356da7b3a637f061e25 Mon Sep 17 00:00:00 2001 From: Solomon Laing Date: Sun, 6 Jun 2021 12:07:29 +0930 Subject: [PATCH 4/5] updated code (started to) for new api, npm install is busted due to out of date deps I think, moving to different computer --- src/app/projects/projects.service.ts | 22 ++-------------------- src/app/shared/models/project.model.ts | 7 +++---- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/src/app/projects/projects.service.ts b/src/app/projects/projects.service.ts index fa29dfb..c77cffc 100644 --- a/src/app/projects/projects.service.ts +++ b/src/app/projects/projects.service.ts @@ -43,7 +43,7 @@ export class ProjectsService { * I am actively avoiding any kind of environment management, this is a very basic site and currently this is the only api call. */ - private PROJECT_API_URL = "https://cms.inkletblot.com/api/json" + private PROJECT_API_URL = "https://cms.inkletblot.com/" constructor(private http: HttpClient, private router: Router) { } @@ -61,16 +61,7 @@ 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 - }); - } + this.allProjects = response; // filter out different categories here currently only one } }, @@ -97,13 +88,4 @@ export class ProjectsService { 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/project.model.ts b/src/app/shared/models/project.model.ts index 28dec90..196064d 100644 --- a/src/app/shared/models/project.model.ts +++ b/src/app/shared/models/project.model.ts @@ -1,7 +1,6 @@ export interface Project { - title: string, - description: string, - ct: string, slug: string, - body: string + date: string, + category: string, + content: string } \ No newline at end of file From ac430a46d1edc4f0be24d0f53f4f0a2b307e786e Mon Sep 17 00:00:00 2001 From: Solomon Laing Date: Sun, 6 Jun 2021 13:27:11 +0930 Subject: [PATCH 5/5] first release of projects ready --- .../project-card/project-card.component.html | 3 +- .../project-card/project-card.component.scss | 2 +- .../projects/project/project.component.html | 3 +- .../projects/project/project.component.scss | 10 +++ src/app/projects/project/project.component.ts | 11 +-- src/app/projects/projects.component.ts | 2 +- src/app/projects/projects.service.ts | 27 +++++- src/app/shared/models/project.model.ts | 1 + src/styles.scss | 90 +++++++++++++++++++ 9 files changed, 134 insertions(+), 15 deletions(-) diff --git a/src/app/projects/project-card/project-card.component.html b/src/app/projects/project-card/project-card.component.html index 6cc1921..b257702 100644 --- a/src/app/projects/project-card/project-card.component.html +++ b/src/app/projects/project-card/project-card.component.html @@ -1,4 +1,3 @@ -

{{project.title}}

-

{{project.description}}

+ {{project.title + " - " + project.date}}
\ 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 d902910..11d9562 100644 --- a/src/app/projects/project-card/project-card.component.scss +++ b/src/app/projects/project-card/project-card.component.scss @@ -11,7 +11,7 @@ border: colors.$inklets-color-highlight-bg 2px dashed; background-color: colors.$inklets-color-fg; text-decoration: none; - padding: 0 20px 0 20px; + padding: 5px 20px 5px 20px; } a:hover { diff --git a/src/app/projects/project/project.component.html b/src/app/projects/project/project.component.html index dc66179..c6545ee 100644 --- a/src/app/projects/project/project.component.html +++ b/src/app/projects/project/project.component.html @@ -1,2 +1 @@ -

project works!

-{{project.title}} + diff --git a/src/app/projects/project/project.component.scss b/src/app/projects/project/project.component.scss index e69de29..7bfa459 100644 --- a/src/app/projects/project/project.component.scss +++ b/src/app/projects/project/project.component.scss @@ -0,0 +1,10 @@ +@use 'src/app/shared/styles/_variables.color' as colors; + +:host { + display: flex; + flex-direction: column; + flex-grow: 1; + overflow-y: auto; + padding: 0 20px 0 20px; + margin: 0 140px 10px 140px; +} \ No newline at end of file diff --git a/src/app/projects/project/project.component.ts b/src/app/projects/project/project.component.ts index ce93a3e..9325d51 100644 --- a/src/app/projects/project/project.component.ts +++ b/src/app/projects/project/project.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @@ -8,17 +8,18 @@ import { ProjectsService } from '../projects.service'; @Component({ selector: 'app-project', templateUrl: './project.component.html', + // encapsulation: ViewEncapsulation.None, styleUrls: ['./project.component.scss'] }) export class ProjectComponent implements OnInit, OnDestroy { _unsubscribe$: Subject = new Subject(); project: Project = { - title: '', - description: '', slug: '', - ct: '', - body: '', + title: '', + date: '', + category: '', + content: '', }; constructor( diff --git a/src/app/projects/projects.component.ts b/src/app/projects/projects.component.ts index 17af914..6da1e8b 100644 --- a/src/app/projects/projects.component.ts +++ b/src/app/projects/projects.component.ts @@ -26,7 +26,7 @@ export class ProjectsComponent implements OnInit, OnDestroy { .subscribe((result: Project[]) => { this.uncategorizedProjects = result; }); - this.projectsService.getInvoicesToApprove(); + this.projectsService.getProjects(); } ngOnDestroy(): void { diff --git a/src/app/projects/projects.service.ts b/src/app/projects/projects.service.ts index c77cffc..fc374fb 100644 --- a/src/app/projects/projects.service.ts +++ b/src/app/projects/projects.service.ts @@ -43,7 +43,7 @@ export class ProjectsService { * I am actively avoiding any kind of environment management, this is a very basic site and currently this is the only api call. */ - private PROJECT_API_URL = "https://cms.inkletblot.com/" + private PROJECT_API_URL = "https://cms.inkletblot.com" constructor(private http: HttpClient, private router: Router) { } @@ -53,9 +53,9 @@ export class ProjectsService { }) }; - getInvoicesToApprove(): void { + getProjects(): void { this.http - .get(`${this.PROJECT_API_URL}`, this.httpOptions) + .get(`${this.PROJECT_API_URL}/posts`, this.httpOptions) .subscribe( (response: Project[]) => { if (response) { @@ -71,6 +71,25 @@ export class ProjectsService { ); } + getSingleProject(id: string): void { + this.http + .get(`${this.PROJECT_API_URL}/post/${id}`, this.httpOptions) + .subscribe( + (response: Project) => { + 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.currentProject = response; + // filter out different categories here currently only one + } + }, + (error) => { + this.apiErrored = true; + this.router.navigate(['not-found']) + } + ); + } + /** * 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. @@ -85,7 +104,7 @@ export class ProjectsService { } }) if (!found) { - this.router.navigate(['not-found']) + this.getSingleProject(id) } } } diff --git a/src/app/shared/models/project.model.ts b/src/app/shared/models/project.model.ts index 196064d..522b454 100644 --- a/src/app/shared/models/project.model.ts +++ b/src/app/shared/models/project.model.ts @@ -1,5 +1,6 @@ export interface Project { slug: string, + title: string, date: string, category: string, content: string diff --git a/src/styles.scss b/src/styles.scss index 9e71b2c..e5950b8 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -10,4 +10,94 @@ body { font-family: Roboto, 'Helvetica Neue', sans-serif; background-color: colors.$inklets-color-black; color: colors.$inklets-color-white; +} + +/* + + Codehilite styles for api content + +*/ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #979797; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #979797; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.codehilite .hll { background-color: #ffffcc } +.codehilite { background: #000000; padding: 5px; } +.codehilite .c { color: #408080; font-style: italic } /* Comment */ +.codehilite .err { border: 1px solid #FF0000 } /* Error */ +.codehilite .k { color: #008000; font-weight: bold } /* Keyword */ +.codehilite .o { color: #666666 } /* Operator */ +.codehilite .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ +.codehilite .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +.codehilite .cp { color: #BC7A00 } /* Comment.Preproc */ +.codehilite .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ +.codehilite .c1 { color: #408080; font-style: italic } /* Comment.Single */ +.codehilite .cs { color: #408080; font-style: italic } /* Comment.Special */ +.codehilite .gd { color: #A00000 } /* Generic.Deleted */ +.codehilite .ge { font-style: italic } /* Generic.Emph */ +.codehilite .gr { color: #FF0000 } /* Generic.Error */ +.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.codehilite .gi { color: #00A000 } /* Generic.Inserted */ +.codehilite .go { color: #888888 } /* Generic.Output */ +.codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.codehilite .gs { font-weight: bold } /* Generic.Strong */ +.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.codehilite .gt { color: #0044DD } /* Generic.Traceback */ +.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.codehilite .kp { color: #008000 } /* Keyword.Pseudo */ +.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.codehilite .kt { color: #B00040 } /* Keyword.Type */ +.codehilite .m { color: #666666 } /* Literal.Number */ +.codehilite .s { color: #BA2121 } /* Literal.String */ +.codehilite .na { color: #7D9029 } /* Name.Attribute */ +.codehilite .nb { color: #008000 } /* Name.Builtin */ +.codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.codehilite .no { color: #880000 } /* Name.Constant */ +.codehilite .nd { color: #AA22FF } /* Name.Decorator */ +.codehilite .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.codehilite .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.codehilite .nf { color: #0000FF } /* Name.Function */ +.codehilite .nl { color: #A0A000 } /* Name.Label */ +.codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.codehilite .nv { color: #19177C } /* Name.Variable */ +.codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.codehilite .w { color: #bbbbbb } /* Text.Whitespace */ +.codehilite .mb { color: #666666 } /* Literal.Number.Bin */ +.codehilite .mf { color: #666666 } /* Literal.Number.Float */ +.codehilite .mh { color: #666666 } /* Literal.Number.Hex */ +.codehilite .mi { color: #666666 } /* Literal.Number.Integer */ +.codehilite .mo { color: #666666 } /* Literal.Number.Oct */ +.codehilite .sa { color: #BA2121 } /* Literal.String.Affix */ +.codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */ +.codehilite .sc { color: #BA2121 } /* Literal.String.Char */ +.codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.codehilite .s2 { color: #BA2121 } /* Literal.String.Double */ +.codehilite .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.codehilite .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.codehilite .sx { color: #008000 } /* Literal.String.Other */ +.codehilite .sr { color: #BB6688 } /* Literal.String.Regex */ +.codehilite .s1 { color: #BA2121 } /* Literal.String.Single */ +.codehilite .ss { color: #19177C } /* Literal.String.Symbol */ +.codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.codehilite .fm { color: #0000FF } /* Name.Function.Magic */ +.codehilite .vc { color: #19177C } /* Name.Variable.Class */ +.codehilite .vg { color: #19177C } /* Name.Variable.Global */ +.codehilite .vi { color: #19177C } /* Name.Variable.Instance */ +.codehilite .vm { color: #19177C } /* Name.Variable.Magic */ +.codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */ + + +* a { + text-decoration: none; + color: colors.$inklets-color-fg; +} + +* a:hover { + color: colors.$inklets-color-highlight-fg; } \ No newline at end of file