diff --git a/angular.json b/angular.json index ed3f93d..be39ad0 100644 --- a/angular.json +++ b/angular.json @@ -29,6 +29,7 @@ ], "styles": [ "node_modules/bootstrap/dist/css/bootstrap.min.css", + "node_modules/bootstrap-icons/font/bootstrap-icons.min.css", "src/styles.css" ], "scripts": [ diff --git a/package-lock.json b/package-lock.json index ed0b417..275ea54 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@ng-bootstrap/ng-bootstrap": "^18.0.0", "@popperjs/core": "^2.11.8", "bootstrap": "^5.3.3", + "bootstrap-icons": "^1.11.3", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.15.0" @@ -5840,6 +5841,22 @@ "@popperjs/core": "^2.11.8" } }, + "node_modules/bootstrap-icons": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.3.tgz", + "integrity": "sha512-+3lpHrCw/it2/7lBL15VR0HEumaBss0+f/Lb6ZvHISn1mlK83jjFpooTLsMWbIjJMDjDjOExMsTxnXSIT4k4ww==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "license": "MIT" + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", diff --git a/package.json b/package.json index f072623..f4ab0c1 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@ng-bootstrap/ng-bootstrap": "^18.0.0", "@popperjs/core": "^2.11.8", "bootstrap": "^5.3.3", + "bootstrap-icons": "^1.11.3", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.15.0" @@ -39,4 +40,4 @@ "karma-jasmine-html-reporter": "~2.1.0", "typescript": "~5.7.2" } -} \ No newline at end of file +} diff --git a/src/app/app.component.html b/src/app/app.component.html index caeea25..10d0c83 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,2 +1,19 @@ + diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 0196821..d51da8f 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -1,5 +1,5 @@ -import { TestBed } from '@angular/core/testing'; -import { AppComponent } from './app.component'; +import {TestBed} from '@angular/core/testing'; +import {AppComponent} from './app.component'; describe('AppComponent', () => { beforeEach(async () => { diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 42eed63..2e9431a 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,13 +1,17 @@ -import { Component } from '@angular/core'; -import { RouterOutlet } from '@angular/router'; +import {Component} from '@angular/core'; +import {RouterLink, RouterLinkActive, RouterOutlet} from '@angular/router'; import {ToastContainerComponent} from '../components/toast-container/toast-container/toast-container.component'; +import {NgbCollapse} from '@ng-bootstrap/ng-bootstrap'; +import {routes} from './app.routes'; @Component({ selector: 'app-root', - imports: [RouterOutlet, ToastContainerComponent], + imports: [RouterOutlet, ToastContainerComponent, NgbCollapse, RouterLink, RouterLinkActive], templateUrl: './app.component.html', styleUrl: './app.component.css' }) export class AppComponent { title = 'untitled'; + isMenuCollapsed: boolean = true; + protected readonly routes = routes; } diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index e56aaee..e6930b8 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -1,4 +1,4 @@ -import { Routes } from '@angular/router'; +import {Routes} from '@angular/router'; import {ShowsComponent} from '../pages/shows/shows.component'; export const routes: Routes = [ diff --git a/src/components/create-modal/create-modal/create-modal.component.html b/src/components/create-modal/create-modal/create-modal.component.html index 9527110..69e43d5 100644 --- a/src/components/create-modal/create-modal/create-modal.component.html +++ b/src/components/create-modal/create-modal/create-modal.component.html @@ -2,8 +2,9 @@ - + + diff --git a/src/components/create-modal/create-modal/create-modal.component.spec.ts b/src/components/create-modal/create-modal/create-modal.component.spec.ts index c52da61..66f91f8 100644 --- a/src/components/create-modal/create-modal/create-modal.component.spec.ts +++ b/src/components/create-modal/create-modal/create-modal.component.spec.ts @@ -1,6 +1,6 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import {ComponentFixture, TestBed} from '@angular/core/testing'; -import { CreateModalComponent } from './create-modal.component'; +import {CreateModalComponent} from './create-modal.component'; describe('CreateModalComponent', () => { let component: CreateModalComponent; @@ -10,7 +10,7 @@ describe('CreateModalComponent', () => { await TestBed.configureTestingModule({ imports: [CreateModalComponent] }) - .compileComponents(); + .compileComponents(); fixture = TestBed.createComponent(CreateModalComponent); component = fixture.componentInstance; diff --git a/src/components/delete-modal/delete-modal.component.css b/src/components/delete-modal/delete-modal.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/components/delete-modal/delete-modal.component.html b/src/components/delete-modal/delete-modal.component.html new file mode 100644 index 0000000..2d87fad --- /dev/null +++ b/src/components/delete-modal/delete-modal.component.html @@ -0,0 +1,25 @@ + + + diff --git a/src/components/delete-modal/delete-modal.component.spec.ts b/src/components/delete-modal/delete-modal.component.spec.ts new file mode 100644 index 0000000..ee8a25e --- /dev/null +++ b/src/components/delete-modal/delete-modal.component.spec.ts @@ -0,0 +1,23 @@ +import {ComponentFixture, TestBed} from '@angular/core/testing'; + +import {DeleteModalComponent} from './delete-modal.component'; + +describe('DeleteModalComponent', () => { + let component: DeleteModalComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [DeleteModalComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(DeleteModalComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/components/delete-modal/delete-modal.component.ts b/src/components/delete-modal/delete-modal.component.ts new file mode 100644 index 0000000..94a76a5 --- /dev/null +++ b/src/components/delete-modal/delete-modal.component.ts @@ -0,0 +1,46 @@ +import {Component, inject} from '@angular/core'; +import {NgbActiveModal, NgbCollapse} from '@ng-bootstrap/ng-bootstrap'; +import {FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators} from '@angular/forms'; + +@Component({ + selector: 'app-delete-modal', + imports: [ + NgbCollapse, + FormsModule, + ReactiveFormsModule + ], + templateUrl: './delete-modal.component.html', + styleUrl: './delete-modal.component.css' +}) +export class DeleteModalComponent { + protected activeModal: NgbActiveModal = inject(NgbActiveModal) + showName: string = "" + formHidden: boolean = true; + buttonDisabled: boolean = false; + confirmationForm: FormGroup + + constructor() { + this.confirmationForm = new FormGroup({ + name: new FormControl("", Validators.required) + }) + } + + + deletePressed() { + if (this.formHidden) { + const regex = new RegExp(this.showName) + const control = new FormControl("", [Validators.required, Validators.pattern(regex)]) + this.confirmationForm.setControl("name", control) + this.formHidden = false; + this.buttonDisabled = true; + } else { + this.formSubmitted() + } + } + + formSubmitted() { + if (this.confirmationForm.valid) { + this.activeModal.close(true) + } + } +} diff --git a/src/components/toast-container/toast-container/toast-container.component.html b/src/components/toast-container/toast-container/toast-container.component.html index 35b3224..05ee02a 100644 --- a/src/components/toast-container/toast-container/toast-container.component.html +++ b/src/components/toast-container/toast-container/toast-container.component.html @@ -3,5 +3,6 @@ [header]="toast.header || ''" [autohide]="true" [delay]="toast.delay || 5000" (hidden)="toastService.remove(toast)" [animation]="true" [class]="toast.htmlClass" - >{{ toast.body }} + >{{ toast.body }} + } diff --git a/src/components/toast-container/toast-container/toast-container.component.spec.ts b/src/components/toast-container/toast-container/toast-container.component.spec.ts index d052b36..e9df657 100644 --- a/src/components/toast-container/toast-container/toast-container.component.spec.ts +++ b/src/components/toast-container/toast-container/toast-container.component.spec.ts @@ -1,6 +1,6 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import {ComponentFixture, TestBed} from '@angular/core/testing'; -import { ToastContainerComponent } from './toast-container.component'; +import {ToastContainerComponent} from './toast-container.component'; describe('ToastContainerComponent', () => { let component: ToastContainerComponent; @@ -10,7 +10,7 @@ describe('ToastContainerComponent', () => { await TestBed.configureTestingModule({ imports: [ToastContainerComponent] }) - .compileComponents(); + .compileComponents(); fixture = TestBed.createComponent(ToastContainerComponent); component = fixture.componentInstance; diff --git a/src/index.html b/src/index.html index b8f5f32..3d83aaf 100644 --- a/src/index.html +++ b/src/index.html @@ -8,6 +8,6 @@ - + diff --git a/src/interfaces/shows-api-deletion.ts b/src/interfaces/shows-api-deletion.ts new file mode 100644 index 0000000..207da69 --- /dev/null +++ b/src/interfaces/shows-api-deletion.ts @@ -0,0 +1,4 @@ +export interface ShowsApiDeletion { + status: string + message: string +} diff --git a/src/main.ts b/src/main.ts index ee35435..d0a3c14 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,8 +1,8 @@ /// -import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; -import { AppComponent } from './app/app.component'; +import {bootstrapApplication} from '@angular/platform-browser'; +import {appConfig} from './app/app.config'; +import {AppComponent} from './app/app.component'; bootstrapApplication(AppComponent, appConfig) .catch((err) => console.error(err)); diff --git a/src/pages/shows/shows.component.html b/src/pages/shows/shows.component.html index 12fb737..924e8b1 100644 --- a/src/pages/shows/shows.component.html +++ b/src/pages/shows/shows.component.html @@ -6,6 +6,12 @@
{{ show.title }}

{{ show.date | date }}

+ +
} diff --git a/src/pages/shows/shows.component.spec.ts b/src/pages/shows/shows.component.spec.ts index 6f18b21..e0552f2 100644 --- a/src/pages/shows/shows.component.spec.ts +++ b/src/pages/shows/shows.component.spec.ts @@ -1,6 +1,6 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import {ComponentFixture, TestBed} from '@angular/core/testing'; -import { ShowsComponent } from './shows.component'; +import {ShowsComponent} from './shows.component'; describe('ShowsComponent', () => { let component: ShowsComponent; @@ -10,7 +10,7 @@ describe('ShowsComponent', () => { await TestBed.configureTestingModule({ imports: [ShowsComponent] }) - .compileComponents(); + .compileComponents(); fixture = TestBed.createComponent(ShowsComponent); component = fixture.componentInstance; diff --git a/src/pages/shows/shows.component.ts b/src/pages/shows/shows.component.ts index 6d25a13..44add53 100644 --- a/src/pages/shows/shows.component.ts +++ b/src/pages/shows/shows.component.ts @@ -4,10 +4,12 @@ import {Show} from '../../interfaces/show'; import {ShowsApiResponse} from '../../interfaces/shows-api-response'; import {Toast} from '../../interfaces/toast'; import {ToastService} from '../../services/toast/toast.service'; -import {NgbModal} from '@ng-bootstrap/ng-bootstrap'; +import {NgbModal, NgbModalRef} from '@ng-bootstrap/ng-bootstrap'; import {CreateModalComponent} from '../../components/create-modal/create-modal/create-modal.component'; import {DatePipe} from '@angular/common'; import {ShowsApiIdResponse} from '../../interfaces/shows-api-id-response'; +import {DeleteModalComponent} from '../../components/delete-modal/delete-modal.component'; +import {ShowsApiDeletion} from '../../interfaces/shows-api-deletion'; @Component({ selector: 'app-shows', @@ -51,13 +53,38 @@ export class ShowsComponent { this.api.getShow(result).subscribe({ next: (response: ShowsApiIdResponse) => { - console.log(response.show) this.shows.push(response.show) }, error: (err: any) => { console.error(`Error: ${err}`) - }, complete: () => {} + }, complete: () => { + } }) } ) } + + deleteShow(show: Show) { + let modal: NgbModalRef = this.modalService.open(DeleteModalComponent) + modal.componentInstance.showName = show.title; + modal.result.then( + (result) => { + if (result) { + this.api.deleteShw(show._id).subscribe({ + next: (response: ShowsApiDeletion) => { + // Do nothing + }, error: (err: any) => { + console.log(err) + }, complete: () => { + this.toastService.show({body: "Show deleted!"}) + this.shows = this.shows.filter(((s: Show) => s != show)) + } + } + ) + } + }, + (result) => { + // Dismissed, do nothing + } + ) + } } diff --git a/src/services/shows/shows-api.service.spec.ts b/src/services/shows/shows-api.service.spec.ts index 2fe78f0..6dfa05a 100644 --- a/src/services/shows/shows-api.service.spec.ts +++ b/src/services/shows/shows-api.service.spec.ts @@ -1,6 +1,6 @@ -import { TestBed } from '@angular/core/testing'; +import {TestBed} from '@angular/core/testing'; -import { ShowsApiService } from './shows-api.service'; +import {ShowsApiService} from './shows-api.service'; describe('ShowsApiService', () => { let service: ShowsApiService; diff --git a/src/services/shows/shows-api.service.ts b/src/services/shows/shows-api.service.ts index d2f0e2e..4a65bfd 100644 --- a/src/services/shows/shows-api.service.ts +++ b/src/services/shows/shows-api.service.ts @@ -4,6 +4,7 @@ import {Observable} from 'rxjs'; import {ShowsApiResponse} from '../../interfaces/shows-api-response'; import {ShowsApiCreation} from '../../interfaces/shows-api-creation'; import {ShowsApiIdResponse} from '../../interfaces/shows-api-id-response'; +import {ShowsApiDeletion} from '../../interfaces/shows-api-deletion'; @Injectable({ providedIn: 'root' @@ -23,10 +24,14 @@ export class ShowsApiService { } getShow(id: string): Observable { - return this.http.get(this.showsEndpoint + "id/" + id ) + return this.http.get(this.showsEndpoint + "id/" + id) } sendShow(newShow: {}) { return this.http.post(this.showsEndpoint, newShow) } + + deleteShw(id: string): Observable { + return this.http.delete(this.showsEndpoint + "id/" + id) + } } diff --git a/src/services/toast/toast.service.spec.ts b/src/services/toast/toast.service.spec.ts index e0413db..577c8aa 100644 --- a/src/services/toast/toast.service.spec.ts +++ b/src/services/toast/toast.service.spec.ts @@ -1,6 +1,6 @@ -import { TestBed } from '@angular/core/testing'; +import {TestBed} from '@angular/core/testing'; -import { ToastService } from './toast.service'; +import {ToastService} from './toast.service'; describe('ToastService', () => { let service: ToastService; diff --git a/src/services/toast/toast.service.ts b/src/services/toast/toast.service.ts index d760383..57f9db7 100644 --- a/src/services/toast/toast.service.ts +++ b/src/services/toast/toast.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import {Injectable} from '@angular/core'; import {Toast} from '../../interfaces/toast'; @Injectable({