diff --git a/angular.json b/angular.json index a792305..95c54f0 100644 --- a/angular.json +++ b/angular.json @@ -20,18 +20,11 @@ "outputPath": "dist/angular-signals-course", "index": "src/index.html", "browser": "src/main.ts", - "polyfills": [ - "zone.js" - ], + "polyfills": ["zone.js"], "tsConfig": "tsconfig.app.json", "inlineStyleLanguage": "scss", - "assets": [ - "src/favicon.ico", - "src/assets" - ], - "styles": [ - "src/styles.scss" - ], + "assets": ["src/favicon.ico", "src/assets"], + "styles": ["src/styles.scss"], "scripts": [] }, "configurations": { @@ -85,19 +78,11 @@ "test": { "builder": "@angular-devkit/build-angular:karma", "options": { - "polyfills": [ - "zone.js", - "zone.js/testing" - ], + "polyfills": ["zone.js", "zone.js/testing"], "tsConfig": "tsconfig.spec.json", "inlineStyleLanguage": "scss", - "assets": [ - "src/favicon.ico", - "src/assets" - ], - "styles": [ - "src/styles.scss" - ], + "assets": ["src/favicon.ico", "src/assets"], + "styles": ["src/styles.scss"], "scripts": [] } } diff --git a/server/get-courses.route.ts b/server/get-courses.route.ts index 136f055..5e3e28b 100644 --- a/server/get-courses.route.ts +++ b/server/get-courses.route.ts @@ -11,18 +11,18 @@ export function getAllCourses(req: Request, res: Response) { return; */ - console.log(`Called GET /api/courses`); - setTimeout(() => { - console.log(`Returning GET /api/courses`); + setTimeout(() => { res.status(200).json({courses:Object.values(COURSES)}); - }, 1000); + }, 1500); + } + export function getCourseById(req: Request, res: Response) { setTimeout(() => { @@ -33,6 +33,6 @@ export function getCourseById(req: Request, res: Response) { const course = courses.find(course => course.id == courseId); res.status(200).json(course); - }) + }, 1500); } diff --git a/src/app/app.component.html b/src/app/app.component.html index ba4e958..0261f66 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -24,18 +24,14 @@ resource() Demo - @if(isLoggedIn()) { - - exit_to_app - Logout - - } - @else { - - account_circle - Login - - } + + account_circle + Login + + + exit_to_app + Logout + @@ -55,9 +51,6 @@ - - - diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 723bbaf..765bb25 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -7,7 +7,6 @@ import {MatToolbar} from "@angular/material/toolbar"; import {MatIconButton} from "@angular/material/button"; import {LoadingIndicatorComponent} from "./loading/loading.component"; import {MessagesComponent} from "./messages/messages.component"; -import {AuthService} from "./services/auth.service"; @Component({ @@ -21,11 +20,5 @@ import {AuthService} from "./services/auth.service"; }) export class AppComponent { - authService = inject(AuthService); - isLoggedIn = this.authService.isLoggedIn; - - onLogout() { - this.authService.logout(); - } } diff --git a/src/app/app.config.ts b/src/app/app.config.ts index ac2751e..7dc9105 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -4,17 +4,13 @@ import {provideRouter} from '@angular/router'; import {routes} from './app.routes'; import {provideAnimationsAsync} from '@angular/platform-browser/animations/async'; import { provideHttpClient, withFetch, withInterceptors } from "@angular/common/http"; -import {loadingInterceptor} from "./services/loading.interceptor"; export const appConfig: ApplicationConfig = { providers: [ provideRouter(routes), provideAnimationsAsync(), provideHttpClient( - withFetch(), - withInterceptors([ - //loadingInterceptor - ]) + withFetch() ) ] }; diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 82ddad4..b647aff 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -2,27 +2,13 @@ import {Routes} from '@angular/router'; import {HomeComponent} from "./home/home.component"; import {LoginComponent} from "./login/login.component"; import {LessonsComponent} from "./lessons/lessons.component"; -import {isUserAuthenticated} from "./guards/auth.guard"; -import {CourseComponent} from "./course/course.component"; -import {courseResolver} from "./course/course.resolver"; -import {courseLessonsResolver} from "./course/course-lessons.resolver"; -import {LinkedSignalDemoComponent} from "./linked-signal/linked-signal-demo.component"; import {ResourceDemoComponent} from "./resource-demo/resource-demo.component"; +import {LinkedSignalDemoComponent} from "./linked-signal/linked-signal-demo.component"; export const routes: Routes = [ { path: '', - component: HomeComponent, - canActivate: [isUserAuthenticated] - }, - { - 'path': 'courses/:courseId', - component: CourseComponent, - canActivate: [isUserAuthenticated], - resolve: { - course: courseResolver, - lessons: courseLessonsResolver - } + component: HomeComponent }, { path: "login", diff --git a/src/app/course-category-combobox/course-category-combobox.component.html b/src/app/course-category-combobox/course-category-combobox.component.html index 104d245..cff45c7 100644 --- a/src/app/course-category-combobox/course-category-combobox.component.html +++ b/src/app/course-category-combobox/course-category-combobox.component.html @@ -1,10 +1,9 @@
- + - diff --git a/src/app/course-category-combobox/course-category-combobox.component.ts b/src/app/course-category-combobox/course-category-combobox.component.ts index 5af50b4..de61e1b 100644 --- a/src/app/course-category-combobox/course-category-combobox.component.ts +++ b/src/app/course-category-combobox/course-category-combobox.component.ts @@ -1,20 +1,16 @@ -import {Component, input, model} from '@angular/core'; -import {CourseCategory} from "../models/course-category.model"; +import { Component, input, model } from '@angular/core'; +import { CourseCategory } from '../models/course-category.model'; +import { MatDialog, MatDialogConfig } from '@angular/material/dialog'; +import { EditCourseDialogData } from '../edit-course-dialog/edit-course-dialog.data.model'; +import { EditCourseDialogComponent } from '../edit-course-dialog/edit-course-dialog.component'; @Component({ - selector: 'course-category-combobox', - imports: [], - templateUrl: './course-category-combobox.component.html', - styleUrl: './course-category-combobox.component.scss' + selector: 'course-category-combobox', + standalone: true, + imports: [], + templateUrl: './course-category-combobox.component.html', + styleUrl: './course-category-combobox.component.scss', }) export class CourseCategoryComboboxComponent { - label = input.required(); - - value = model.required(); - - onCategoryChanged(category: string) { - this.value.set(category as CourseCategory); - } - } diff --git a/src/app/course/course-lessons.resolver.ts b/src/app/course/course-lessons.resolver.ts deleted file mode 100644 index 1d4158b..0000000 --- a/src/app/course/course-lessons.resolver.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {ActivatedRouteSnapshot, ResolveFn, RouterStateSnapshot} from "@angular/router"; -import {Lesson} from "../models/lesson.model"; -import {inject} from "@angular/core"; -import {LessonsService} from "../services/lessons.service"; - - -export const courseLessonsResolver: ResolveFn = - async (route: ActivatedRouteSnapshot, - state: RouterStateSnapshot) => { - const courseId = route.paramMap.get("courseId"); - if (!courseId) { - return []; - } - const lessonsService = inject(LessonsService); - return lessonsService.loadLessons({courseId}); - } diff --git a/src/app/course/course.component.html b/src/app/course/course.component.html index ae826cd..43b6e6b 100644 --- a/src/app/course/course.component.html +++ b/src/app/course/course.component.html @@ -1,20 +1 @@ -
-
-

{{ course()?.title }}

- -
-
- - @for(lesson of lessons(); track lesson.id) { - - - - - } -
- {{lesson.description}} - - {{lesson.duration}} -
-
-
+

course works!

diff --git a/src/app/course/course.component.ts b/src/app/course/course.component.ts index 2803fcc..cc5cb93 100644 --- a/src/app/course/course.component.ts +++ b/src/app/course/course.component.ts @@ -1,24 +1,12 @@ -import {Component, inject, OnInit, signal} from '@angular/core'; -import {Course} from "../models/course.model"; -import {Lesson} from "../models/lesson.model"; -import {ActivatedRoute} from "@angular/router"; +import { Component } from '@angular/core'; @Component({ - selector: 'course', - imports: [], - templateUrl: './course.component.html', - styleUrl: './course.component.scss' + selector: 'course', + standalone: true, + imports: [], + templateUrl: './course.component.html', + styleUrl: './course.component.scss' }) -export class CourseComponent implements OnInit { +export class CourseComponent { - course = signal(null); - - lessons = signal([]); - - route = inject(ActivatedRoute); - - ngOnInit() { - this.course.set(this.route.snapshot.data["course"]); - this.lessons.set(this.route.snapshot.data["lessons"]); - } } diff --git a/src/app/course/course.resolver.ts b/src/app/course/course.resolver.ts deleted file mode 100644 index f9aecc2..0000000 --- a/src/app/course/course.resolver.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {ActivatedRouteSnapshot, ResolveFn, RouterStateSnapshot} from "@angular/router"; -import {Course} from "../models/course.model"; -import {CoursesService} from "../services/courses.service"; -import {inject} from "@angular/core"; - - -export const courseResolver: ResolveFn = - async (route: ActivatedRouteSnapshot, - state: RouterStateSnapshot) => { - const courseId = route.paramMap.get("courseId"); - if (!courseId) { - return null; - } - const coursesService = inject(CoursesService); - return coursesService.getCourseById(courseId); -} diff --git a/src/app/courses-card-list/courses-card-list.component.html b/src/app/courses-card-list/courses-card-list.component.html index 09c00c5..a260d3b 100644 --- a/src/app/courses-card-list/courses-card-list.component.html +++ b/src/app/courses-card-list/courses-card-list.component.html @@ -1,23 +1,22 @@ +@for(course of courses() ;track course.id){ -@for(course of courses(); track course.id) { -
-
- {{course.title}} -
- -
-

{{course.longDescription}}

-
-
- - - -
+
+
+ {{ course.title }}
+ +
+

{{ course.longDescription }}

+
+
+ + + +
+
+ } diff --git a/src/app/courses-card-list/courses-card-list.component.ts b/src/app/courses-card-list/courses-card-list.component.ts index 60e4147..526f578 100644 --- a/src/app/courses-card-list/courses-card-list.component.ts +++ b/src/app/courses-card-list/courses-card-list.component.ts @@ -2,8 +2,7 @@ import {Component, inject, input, output} from '@angular/core'; import {RouterLink} from "@angular/router"; import {Course} from "../models/course.model"; import {MatDialog} from "@angular/material/dialog"; -import {openEditCourseDialog} from "../edit-course-dialog/edit-course-dialog.component"; -import {firstValueFrom} from "rxjs"; +import { openEditCourseDialog } from '../edit-course-dialog/edit-course-dialog.component'; @Component({ selector: 'courses-card-list', @@ -14,33 +13,28 @@ import {firstValueFrom} from "rxjs"; styleUrl: './courses-card-list.component.scss' }) export class CoursesCardListComponent { - - courses = input.required(); - + courses =input.required({ + alias:"data" + }); courseUpdated = output(); - - courseDeleted = output(); - - dialog = inject(MatDialog); - - async onEditCourse(course: Course) { + constructor(){ + } +dialog=inject(MatDialog) + async onEdiCourse(course:Course) { + console.log(course) const newCourse = await openEditCourseDialog( this.dialog, { - mode: "update", - title: "Update Existing Course", - course + mode:"update", + title:"Update Existing Course", + course } ) - if (!newCourse) { + if(!newCourse){ return; } - console.log(`Course edited:`, newCourse); - this.courseUpdated.emit(newCourse); - } - - onCourseDeleted(course: Course) { - this.courseDeleted.emit(course.id); + console.log('course edited: ',newCourse); + this.courseUpdated.emit(newCourse) } } diff --git a/src/app/edit-course-dialog/edit-course-dialog.component.html b/src/app/edit-course-dialog/edit-course-dialog.component.html index a7d6ce9..0017cde 100644 --- a/src/app/edit-course-dialog/edit-course-dialog.component.html +++ b/src/app/edit-course-dialog/edit-course-dialog.component.html @@ -1,43 +1,39 @@ - +
- -

{{data.title}}

+

{{ data.title }}

- +
-
- +
+ + +
- +
+ - - - - +
-
diff --git a/src/app/edit-course-dialog/edit-course-dialog.component.ts b/src/app/edit-course-dialog/edit-course-dialog.component.ts index 09d4617..9468fe9 100644 --- a/src/app/edit-course-dialog/edit-course-dialog.component.ts +++ b/src/app/edit-course-dialog/edit-course-dialog.component.ts @@ -1,28 +1,33 @@ -import {Component, effect, inject, signal} from '@angular/core'; -import {MAT_DIALOG_DATA, MatDialog, MatDialogConfig, MatDialogRef} from "@angular/material/dialog"; -import {Course} from "../models/course.model"; -import {EditCourseDialogData} from "./edit-course-dialog.data.model"; -import {CoursesService} from "../services/courses.service"; -import {LoadingIndicatorComponent} from "../loading/loading.component"; -import {FormBuilder, ReactiveFormsModule} from '@angular/forms'; -import {CourseCategoryComboboxComponent} from "../course-category-combobox/course-category-combobox.component"; -import {CourseCategory} from "../models/course-category.model"; -import {firstValueFrom} from "rxjs"; +import { Component, effect, inject, signal } from '@angular/core'; +import { + MAT_DIALOG_DATA, + MatDialog, + MatDialogConfig, + MatDialogRef, +} from '@angular/material/dialog'; +import { Course } from '../models/course.model'; +import { EditCourseDialogData } from './edit-course-dialog.data.model'; +import { CoursesService } from '../services/courses.service'; +import { LoadingIndicatorComponent } from '../loading/loading.component'; +import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; +import { CourseCategoryComboboxComponent } from '../course-category-combobox/course-category-combobox.component'; +import { CourseCategory } from '../models/course-category.model'; +import { firstValueFrom } from 'rxjs'; +import { saveCourse } from '../../../server/save-course.route'; @Component({ - selector: 'edit-course-dialog', - imports: [ - LoadingIndicatorComponent, - ReactiveFormsModule, - CourseCategoryComboboxComponent - ], - templateUrl: './edit-course-dialog.component.html', - styleUrl: './edit-course-dialog.component.scss' + selector: 'edit-course-dialog', + standalone: true, + imports: [ + LoadingIndicatorComponent, + ReactiveFormsModule, + CourseCategoryComboboxComponent, + ], + templateUrl: './edit-course-dialog.component.html', + styleUrl: './edit-course-dialog.component.scss', }) export class EditCourseDialogComponent { - dialogRef = inject(MatDialogRef); - data: EditCourseDialogData = inject(MAT_DIALOG_DATA); fb = inject(FormBuilder); @@ -30,82 +35,49 @@ export class EditCourseDialogComponent { form = this.fb.group({ title: [''], longDescription: [''], - iconUrl: [''] + iconUrl: [''], + category: [''], }); - - courseService = inject(CoursesService); - - category = signal("BEGINNER"); - + couseService = inject(CoursesService); constructor() { this.form.patchValue({ title: this.data?.course?.title, longDescription: this.data?.course?.longDescription, - iconUrl: this.data?.course?.iconUrl + category: this.data?.course?.category, + iconUrl: this.data.course?.iconUrl, }); - this.category.set(this.data?.course?.category ?? "BEGINNER"); - effect(() => { - console.log(`Course category bi-directional binding: - ${this.category()}`); - }) } onClose() { this.dialogRef.close(); } - async onSave() { - const courseProps = - this.form.value as Partial; - courseProps.category = this.category(); - if (this.data?.mode === "update") { + const courseProps = this.form.value as Partial; + if (this.data?.mode === 'update') { await this.saveCourse(this.data?.course!.id, courseProps); } - else if (this.data?.mode === "create") { - await this.createCourse(courseProps); - } } - - async createCourse(course: Partial) { + async saveCourse(courseId: string, changes: Partial) { try { - const newCourse = await this.courseService.createCourse(course); - this.dialogRef.close(newCourse); - } - catch (err) { + const updatedCourse =await this.couseService.updateCourse(courseId, changes); + this.dialogRef.close(updatedCourse) + } catch (err) { console.error(err); - alert(`Error creating the course.`) + alert(`Faild To Saved Course`); } - } - - async saveCourse(courseId:string, changes: Partial) { - try { - const updatedCourse = - await this.courseService.saveCourse(courseId, changes); - this.dialogRef.close(updatedCourse); - } - catch (err) { - console.error(err); - alert(`Failed to save the course.`); - } - } - - } export async function openEditCourseDialog( dialog: MatDialog, - data: EditCourseDialogData) { + data: EditCourseDialogData +) { const config = new MatDialogConfig(); config.disableClose = true; config.autoFocus = true; - config.width = "400px"; + config.width = '400px'; config.data = data; - const close$ = dialog.open( - EditCourseDialogComponent, - config) - .afterClosed(); - + const close$ = dialog.open(EditCourseDialogComponent, config).afterClosed(); return firstValueFrom(close$); } diff --git a/src/app/guards/auth.guard.ts b/src/app/guards/auth.guard.ts deleted file mode 100644 index 529d55b..0000000 --- a/src/app/guards/auth.guard.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {ActivatedRouteSnapshot, CanActivateFn, Router, RouterStateSnapshot} from "@angular/router"; -import {inject} from "@angular/core"; -import {AuthService} from "../services/auth.service"; - - -export const isUserAuthenticated: CanActivateFn = - (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { - const authService = inject(AuthService); - const router = inject(Router); - if (authService.isLoggedIn()) { - return true; - } - else { - return router.parseUrl('/login') - } - } diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html index e6abc24..b1fdf4c 100644 --- a/src/app/home/home.component.html +++ b/src/app/home/home.component.html @@ -1,33 +1,22 @@
-

All Courses:

+

All Courses

- - - - - - + + - + + + diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts index 3d6faf2..b12a4cb 100644 --- a/src/app/home/home.component.ts +++ b/src/app/home/home.component.ts @@ -1,188 +1,65 @@ import { - afterNextRender, ChangeDetectorRef, + afterNextRender, Component, computed, effect, - EffectRef, ElementRef, inject, Injector, + OnInit, signal, - viewChild } from '@angular/core'; -import {CoursesService} from "../services/courses.service"; -import {Course, sortCoursesBySeqNo} from "../models/course.model"; -import {MatTab, MatTabGroup} from "@angular/material/tabs"; -import {CoursesCardListComponent} from "../courses-card-list/courses-card-list.component"; -import {MatDialog} from "@angular/material/dialog"; -import {MessagesService} from "../messages/messages.service"; -import {catchError, from, interval, Observable, startWith, throwError} from "rxjs"; -import {toObservable, toSignal, outputToObservable, outputFromObservable} from "@angular/core/rxjs-interop"; -import {CoursesServiceWithFetch} from "../services/courses-fetch.service"; -import {openEditCourseDialog} from "../edit-course-dialog/edit-course-dialog.component"; -import {LoadingService} from "../loading/loading.service"; +import { CoursesService } from '../services/courses.service'; +import { Course, sortCoursesBySeqNo } from '../models/course.model'; +import { MatTab, MatTabGroup } from '@angular/material/tabs'; +import { CoursesCardListComponent } from '../courses-card-list/courses-card-list.component'; +import { MatDialog } from '@angular/material/dialog'; +import { MessagesService } from '../messages/messages.service'; +import { catchError, from, Observable, throwError } from 'rxjs'; +import { + toObservable, + toSignal, + outputToObservable, + outputFromObservable, +} from '@angular/core/rxjs-interop'; +import { CoursesServiceWithFetch } from '../services/courses-fetch.service'; @Component({ - selector: 'home', - imports: [ - MatTabGroup, - MatTab, - CoursesCardListComponent - ], - templateUrl: './home.component.html', - styleUrl: './home.component.scss' + selector: 'home', + imports: [MatTabGroup, MatTab, CoursesCardListComponent], + templateUrl: './home.component.html', + styleUrl: './home.component.scss', }) -export class HomeComponent { - +export class HomeComponent implements OnInit { #courses = signal([]); - coursesService = inject(CoursesService); - dialog = inject(MatDialog); - - beginnerCourses = computed(() => { + beginnerCourses = computed(()=>{ const courses = this.#courses(); - return courses.filter(course => - course.category === "BEGINNER") - }); - - advancedCourses = computed(() => { + return courses.filter(course=>course.category ==="BEGINNER") + }) + advancedCourses = computed(()=>{ const courses = this.#courses(); - return courses.filter(course => - course.category === "ADVANCED") - }); - - messageService = inject(MessagesService); - - beginnersList = viewChild("beginnersList"); + return courses.filter(course=>course.category ==="ADVANCED") + }) - constructor() { + constructor(){ + this.LoadCourses().then(()=>console.log(`all courses loaded`,this.#courses())); - effect(() => { - console.log(`beginnersList: `, this.beginnersList()) + effect(()=>{ + console.log(`Beginner courses: `,this.beginnerCourses() ) + console.log(`Advanced courses: `,this.advancedCourses() ) }) - - effect(() => { - console.log(`Beginner courses: `, this.beginnerCourses()) - console.log(`Advanced courses: `, this.advancedCourses()) - }); - - this.loadCourses() - .then(() => console.log(`All courses loaded:`, this.#courses())); } + ngOnInit(): void { - async loadCourses() { - try { - const courses = await this.coursesService.loadAllCourses(); - this.#courses.set(courses.sort(sortCoursesBySeqNo)); - } - catch(err) { - this.messageService.showMessage( - `Error loading courses!`, - "error" - ); - console.error(err); - } } - - onCourseUpdated(updatedCourse: Course) { - const courses = this.#courses(); - const newCourses = courses.map(course => ( - course.id === updatedCourse.id ? updatedCourse : course - )); - this.#courses.set(newCourses); - } - - async onCourseDeleted(courseId: string) { + async LoadCourses() { try { - await this.coursesService.deleteCourse(courseId); - const courses = this.#courses(); - const newCourses = courses.filter( - course => course.id !== courseId) - this.#courses.set(newCourses); - } - catch (err) { - console.error(err) - alert(`Error deleting course.`) - } - } - - async onAddCourse() { - const newCourse = await openEditCourseDialog( - this.dialog, - { - mode: "create", - title: "Create New Course" - } - ) - if (!newCourse) { - return; - } - const newCourses = [ - ...this.#courses(), - newCourse - ]; - this.#courses.set(newCourses); - } - - onToObservableExample() { - const numbers = signal(0); - numbers.set(1); - numbers.set(2); - numbers.set(3); - const numbers$ = toObservable(numbers, { - injector: this.injector - }); - numbers.set(4); - numbers$.subscribe(val => { - console.log(`numbers$: `, val) - }) - numbers.set(5); - } - - - injector = inject(Injector); - - onToSignalExample() { - try { - const courses$ = from(this.coursesService.loadAllCourses()) - .pipe( - catchError(err => { - console.log(`Error caught in catchError`, err) - throw err; - }) - ); - const courses = toSignal(courses$, { - injector: this.injector, - rejectErrors: true - }) - effect(() => { - console.log(`Courses: `, courses()) - }, { - injector: this.injector - }) - - setInterval(() => { - console.log(`Reading courses signal: `, courses()) - }, 1000) - - } - catch (err) { - console.log(`Error in catch block: `, err) + const courses = await this.coursesService.LoadCourses(); + this.#courses.set(courses.sort(sortCoursesBySeqNo)); + } catch (err) { + alert(`error loading courses`); + console.log(err); } - } - } - - - - - - - - - - - - - diff --git a/src/app/lessons/lesson-detail/lesson-detail.component.html b/src/app/lessons/lesson-detail/lesson-detail.component.html index c2c8b67..f1a1e70 100644 --- a/src/app/lessons/lesson-detail/lesson-detail.component.html +++ b/src/app/lessons/lesson-detail/lesson-detail.component.html @@ -4,19 +4,18 @@

Edit Lesson

- +
- - diff --git a/src/app/lessons/lesson-detail/lesson-detail.component.ts b/src/app/lessons/lesson-detail/lesson-detail.component.ts index 00ab57e..f13c2f8 100644 --- a/src/app/lessons/lesson-detail/lesson-detail.component.ts +++ b/src/app/lessons/lesson-detail/lesson-detail.component.ts @@ -14,29 +14,6 @@ import {MessagesService} from "../../messages/messages.service"; }) export class LessonDetailComponent { - lesson = input.required(); - lessonUpdated = output(); - cancel = output(); - lessonsService = inject(LessonsService); - messagesService = inject(MessagesService); - onCancel() { - this.cancel.emit(); - } - - async onSave(description:string) { - try { - const lesson = this.lesson(); - const updatedLesson = - await this.lessonsService.saveLesson(lesson!.id, {description}); - this.lessonUpdated.emit(updatedLesson); - } - catch(err) { - console.error(err); - this.messagesService.showMessage(` - Error saving lesson!`, 'error') - } - - } } diff --git a/src/app/lessons/lessons.component.html b/src/app/lessons/lessons.component.html index 253f39a..8ed6283 100644 --- a/src/app/lessons/lessons.component.html +++ b/src/app/lessons/lessons.component.html @@ -1,37 +1,5 @@
- @if (mode() == 'master') { -
-

Search Lessons

-
- - -
-
- - @if (lessons().length > 0) { -
- - @for(lesson of lessons(); track lesson.id) { - - - - - } -
{{lesson.description}}{{lesson.duration}}
-
- } - } - @else { - - }
diff --git a/src/app/lessons/lessons.component.scss b/src/app/lessons/lessons.component.scss index aa1ea57..f9f17a5 100644 --- a/src/app/lessons/lessons.component.scss +++ b/src/app/lessons/lessons.component.scss @@ -1,6 +1,5 @@ @import "../../styles/button"; @import "../../styles/forms"; -@import "../../styles/table"; @include buttonStyles(); @include formStyles(); @@ -24,5 +23,29 @@ margin-left: 10px; } +.table-container { + border: 1px solid #2086fc; + border-radius: 5px; +} + +.results-table { + border-collapse: collapse; + width: 100%; + + tr { + border-bottom: 1px solid #ccc; + cursor: pointer; + } + + tr:last-child { + border-bottom: none; + } + + th, td { + padding: 10px; + text-align: left; + } +} + diff --git a/src/app/lessons/lessons.component.ts b/src/app/lessons/lessons.component.ts index d19b789..8fddebb 100644 --- a/src/app/lessons/lessons.component.ts +++ b/src/app/lessons/lessons.component.ts @@ -13,35 +13,7 @@ import {LessonDetailComponent} from "./lesson-detail/lesson-detail.component"; }) export class LessonsComponent { - mode = signal<'master' | 'detail'>("master"); - lessons = signal([]); - selectedLesson = signal(null); - lessonsService = inject(LessonsService); - searchInput = viewChild.required('search'); - async onSearch() { - const query = this.searchInput()?.nativeElement.value; - console.log('search query', query); - const results = - await this.lessonsService.loadLessons({query}); - this.lessons.set(results); - } - - onLessonSelected(lesson: Lesson) { - this.mode.set("detail"); - this.selectedLesson.set(lesson); - } - - onCancel() { - this.mode.set("master"); - } - - onLessonUpdated(lesson: Lesson) { - this.lessons.update(lessons => - lessons.map(l => l.id === lesson.id ? lesson : l) - ); - - } } diff --git a/src/app/linked-signal/linked-signal-demo.component.ts b/src/app/linked-signal/linked-signal-demo.component.ts index a30567b..074a5f5 100644 --- a/src/app/linked-signal/linked-signal-demo.component.ts +++ b/src/app/linked-signal/linked-signal-demo.component.ts @@ -27,14 +27,7 @@ export class LinkedSignalDemoComponent { selectedCourse = signal("BEGINNERS"); - quantity = linkedSignal({ - source: () => ({courseCode: this.selectedCourse}), - computation: (source, previous) => { - console.log(`linkedSignal source: `, source.courseCode()); - console.log(`linkedSignal previous: `, previous); - return this.courses.find(c => c.code === source.courseCode())?.defaultQuantity ?? 1 - } - }); + quantity = signal(1); constructor() { diff --git a/src/app/loading/loading.component.html b/src/app/loading/loading.component.html index 4a6c505..e69de29 100644 --- a/src/app/loading/loading.component.html +++ b/src/app/loading/loading.component.html @@ -1,6 +0,0 @@ - -@if (loading()) { -
- -
-} diff --git a/src/app/loading/loading.component.ts b/src/app/loading/loading.component.ts index 0e4910a..27ac027 100644 --- a/src/app/loading/loading.component.ts +++ b/src/app/loading/loading.component.ts @@ -1,7 +1,6 @@ import {Component, inject, Signal} from "@angular/core"; import {MatProgressSpinner} from "@angular/material/progress-spinner"; import {LoadingService} from "./loading.service"; -import {NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router} from "@angular/router"; @Component({ selector: "loading", @@ -11,8 +10,6 @@ import {NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Route }) export class LoadingIndicatorComponent { - loadingService = inject(LoadingService); - loading = this.loadingService.loading; } diff --git a/src/app/loading/loading.service.ts b/src/app/loading/loading.service.ts index fb16e95..4ed254a 100644 --- a/src/app/loading/loading.service.ts +++ b/src/app/loading/loading.service.ts @@ -1,23 +1,8 @@ -import { inject, Injectable, signal} from "@angular/core"; -import { Router } from "@angular/router"; +import {Injectable, signal} from "@angular/core"; @Injectable({ providedIn: "root", }) export class LoadingService { - #loadingSignal = signal(false); - loading = this.#loadingSignal.asReadonly(); - - router = inject(Router); - - - loadingOn() { - this.#loadingSignal.set(true); - } - - loadingOff() { - this.#loadingSignal.set(false); - } - } diff --git a/src/app/loading/skip-loading.component.ts b/src/app/loading/skip-loading.component.ts index aa0e42b..e69de29 100644 --- a/src/app/loading/skip-loading.component.ts +++ b/src/app/loading/skip-loading.component.ts @@ -1,6 +0,0 @@ -import { HttpContextToken } from "@angular/common/http"; - -export const SkipLoading = new HttpContextToken( - () => false -) - diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html index 0586360..2c6ebef 100644 --- a/src/app/login/login.component.html +++ b/src/app/login/login.component.html @@ -1,18 +1,17 @@