diff --git a/src/Application/Features/Courses/Queries/GetAllCourses/GetCourses.cs b/src/Application/Features/Courses/Queries/GetAllCourses/GetCourses.cs index 9c60d4e..e903cb2 100644 --- a/src/Application/Features/Courses/Queries/GetAllCourses/GetCourses.cs +++ b/src/Application/Features/Courses/Queries/GetAllCourses/GetCourses.cs @@ -24,9 +24,12 @@ public async Task Handle(GetCoursesQuery request, CancellationToken .AsNoTracking() .Include(c => c.Categories) .Include(c => c.Chapters) + .Include(c => c.UserCourses) + .Where(c => c.IsPublished.Equals(true)) .ProjectTo(_mapper.ConfigurationProvider) .OrderBy(t => t.Title) .ToListAsync(cancellationToken) }; + } } diff --git a/src/Application/Features/Courses/Queries/GetAllCourses/QueryDto.cs b/src/Application/Features/Courses/Queries/GetAllCourses/QueryDto.cs index fd4786a..1bca33c 100644 --- a/src/Application/Features/Courses/Queries/GetAllCourses/QueryDto.cs +++ b/src/Application/Features/Courses/Queries/GetAllCourses/QueryDto.cs @@ -13,6 +13,8 @@ public class QueryDto public IReadOnlyCollection Categories { get; set; } public IReadOnlyCollection Chapters { get; init; } + public string? AuthorName { get; set; } + public QueryDto() { Categories = Array.Empty(); @@ -24,6 +26,8 @@ private class Mapping : Profile public Mapping() { CreateMap() + .ForMember(dto => dto.AuthorName, + c => c.MapFrom(c => c.UserCourses.FirstOrDefault()!.User!.UserName)) .ForMember(dto => dto.Categories, c => c.MapFrom(c diff --git a/src/UI/package-lock.json b/src/UI/package-lock.json index 3be898c..54bc666 100755 --- a/src/UI/package-lock.json +++ b/src/UI/package-lock.json @@ -59,6 +59,7 @@ "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.1.0", "tailwindcss": "^3.3.5", + "tailwindcss-animated": "^1.0.1", "typescript": "~5.2.2" } }, @@ -16054,6 +16055,15 @@ "node": ">=14.0.0" } }, + "node_modules/tailwindcss-animated": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tailwindcss-animated/-/tailwindcss-animated-1.0.1.tgz", + "integrity": "sha512-u5wusj89ZwP8I+s8WZlaAd7aZTWBN/XEG6QgMKpkIKmAf3xP1A6WYf7oYIKmGaB10UAQaSqWopi/i1ozzZEs8Q==", + "dev": true, + "peerDependencies": { + "tailwindcss": ">=3.1.0" + } + }, "node_modules/tailwindcss/node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", diff --git a/src/UI/package.json b/src/UI/package.json index d10cdce..73bc0be 100755 --- a/src/UI/package.json +++ b/src/UI/package.json @@ -65,6 +65,7 @@ "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.1.0", "tailwindcss": "^3.3.5", + "tailwindcss-animated": "^1.0.1", "typescript": "~5.2.2" } } diff --git a/src/UI/src/app/core/constant/menu.ts b/src/UI/src/app/core/constant/menu.ts index bf2af4d..672d354 100644 --- a/src/UI/src/app/core/constant/menu.ts +++ b/src/UI/src/app/core/constant/menu.ts @@ -3,29 +3,24 @@ import { MenuItem } from '../models/menu.model'; export class Menu { public static pages: MenuItem[] = [ { - group: 'Pages', + group: '', separator: true, items: [ + { + icon:' heroBuildingStorefront', + label: 'Courses', + route: '/courses', + }, { icon: 'heroFolderOpen', label: 'Dashboard', route: '/dashboard', children: [ { label: 'Overview', route: '/dashboard' }, - { label: 'Teaching', route: '/dashboard/teaching' }, - { label: 'Purchased', route: '/dashboard/purchased' }, - - ], - }, - { - icon:' heroBuildingStorefront', - label: 'Courses', - route: '/courses', - children: [ - { label: 'Course store', route: '/courses' }, - { label: 'Saved courses', route: '/teaching' }, + { label: 'My courses', route: '/dashboard/my-courses' }, ], }, + ], }, { @@ -34,7 +29,7 @@ export class Menu { items: [ { icon: 'heroBuildingStorefront', - label: 'Settings', + label: 'Account settings', route: '/settings', }, diff --git a/src/UI/src/app/modules/auth/pages/login/login.component.ts b/src/UI/src/app/modules/auth/pages/login/login.component.ts index 3be4c27..ea90e43 100644 --- a/src/UI/src/app/modules/auth/pages/login/login.component.ts +++ b/src/UI/src/app/modules/auth/pages/login/login.component.ts @@ -63,7 +63,7 @@ export class LoginComponent implements OnInit, OnDestroy{ this.authService.authenticate(email, password) .subscribe({ next: () => { - this._router.navigate(['/dashboard']); + this._router.navigate(['/courses']); }, error: (err: any) => { this.toastr.error(JSON.stringify(err)); diff --git a/src/UI/src/app/modules/dashboard/dashboard-routing.module.ts b/src/UI/src/app/modules/dashboard/dashboard-routing.module.ts index f8f2dc4..53e5ded 100644 --- a/src/UI/src/app/modules/dashboard/dashboard-routing.module.ts +++ b/src/UI/src/app/modules/dashboard/dashboard-routing.module.ts @@ -14,12 +14,12 @@ const routes: Routes = [ canActivate: [AuthGuard], }, { - path: 'teaching', + path: 'my-courses', component: TeachingComponent, canActivate: [AuthGuard], }, { - path: 'teaching/:id', + path: 'my-courses/:id', component: CoursesDetailComponent, canActivate: [AuthGuard], }, diff --git a/src/UI/src/app/modules/dashboard/pages/dashboard/dashboard.component.ts b/src/UI/src/app/modules/dashboard/pages/dashboard/dashboard.component.ts index 9b13950..9fa23e1 100644 --- a/src/UI/src/app/modules/dashboard/pages/dashboard/dashboard.component.ts +++ b/src/UI/src/app/modules/dashboard/pages/dashboard/dashboard.component.ts @@ -24,7 +24,6 @@ export class DashboardComponent implements OnInit{ ngOnInit(): void { this.ds.getDashboardData().subscribe(data => { - console.log(data) }); diff --git a/src/UI/src/app/modules/dashboard/pages/user-courses/courses-detail-component.ts b/src/UI/src/app/modules/dashboard/pages/user-courses/courses-detail-component.ts index 6d3bd77..12cf9a7 100644 --- a/src/UI/src/app/modules/dashboard/pages/user-courses/courses-detail-component.ts +++ b/src/UI/src/app/modules/dashboard/pages/user-courses/courses-detail-component.ts @@ -133,6 +133,7 @@ export class CoursesDetailComponent implements OnInit { }); } + onCourseTitleChange(newTitle: string): void { this.course.title = newTitle; this.isChanged = true; @@ -174,7 +175,6 @@ export class CoursesDetailComponent implements OnInit { // 1. cannot save if the fields are not filled out // 2. must be able to save as draft - console.log(this.course.chapters) this.courseService.saveCourseDraft(this.course.id, this.course).subscribe({ next: (response) => { diff --git a/src/UI/src/app/modules/layout/layout-routing.module.ts b/src/UI/src/app/modules/layout/layout-routing.module.ts index c56fe2f..5f91e30 100644 --- a/src/UI/src/app/modules/layout/layout-routing.module.ts +++ b/src/UI/src/app/modules/layout/layout-routing.module.ts @@ -6,7 +6,7 @@ import { AuthGuard } from 'src/app/core/auth/service/auth-guard'; // looking from perspective comming first and seaing tho pages const routes: Routes = [ { path: '', - redirectTo: 'dashboard', + redirectTo: 'courses', pathMatch: 'full' }, { diff --git a/src/UI/src/app/modules/management/components/boxes/boxes-header/boxes-header.component.html b/src/UI/src/app/modules/management/components/boxes/boxes-header/boxes-header.component.html index b62d5f7..5fdfe89 100644 --- a/src/UI/src/app/modules/management/components/boxes/boxes-header/boxes-header.component.html +++ b/src/UI/src/app/modules/management/components/boxes/boxes-header/boxes-header.component.html @@ -1,6 +1,6 @@
-
-

{{title}}

+
+

{{title}}

{{subTitle}} @@ -14,8 +14,88 @@

+
+ + + +
+ +
+
+

+ + diff --git a/src/UI/src/app/modules/management/components/boxes/boxes-header/boxes-header.component.ts b/src/UI/src/app/modules/management/components/boxes/boxes-header/boxes-header.component.ts index 4286b84..cfa6b91 100644 --- a/src/UI/src/app/modules/management/components/boxes/boxes-header/boxes-header.component.ts +++ b/src/UI/src/app/modules/management/components/boxes/boxes-header/boxes-header.component.ts @@ -15,6 +15,7 @@ import { DialogConfig, DialogService } from '@ngneat/dialog'; import { BoxesModalComponent } from '../boxes-modal/boxes-modal.component'; import { FormGroup, + FormsModule, ReactiveFormsModule, UntypedFormBuilder, } from '@angular/forms'; @@ -40,7 +41,7 @@ interface PostBoxDto { @Component({ selector: 'app-boxes-header', standalone: true, - imports: [CommonModule, ModalComponent], + imports: [CommonModule, ModalComponent,FormsModule], templateUrl: './boxes-header.component.html', styleUrls: ['./boxes-header.component.scss'], }) @@ -48,11 +49,13 @@ export class BoxesHeaderComponent implements OnInit { @Output() dataEmitter = new EventEmitter(); + @Output() searchTermEmitter = new EventEmitter(); @Input() showButton: boolean; private modalSubscription: Subscription; modal: ModalInterface; formGroup: FormGroup; +searchTerm: string; constructor( private fb: UntypedFormBuilder, @@ -91,17 +94,8 @@ export class BoxesHeaderComponent implements OnInit { @Input() isDetail: boolean = true; @ViewChild('template', { static: true }) messageFromDialog: string; - dataFromDialog: PostBoxDto; - - postDataDto: PostBoxDto = { - title: '', - type: '', - image: '', - status: '', - price: 0, - color: '', - description: '', - }; + + ngOnInit() { this.dataEmitter.emit(this.showButton); @@ -111,6 +105,12 @@ export class BoxesHeaderComponent implements OnInit { this.modal.hide(); } + onSearchQueryChange(event: any): void { + this.searchTerm = event.target.value; + this.searchTermEmitter.emit(this.searchTerm); + } + + diff --git a/src/UI/src/app/modules/management/components/courses/course-chapters/course-chapters.component.ts b/src/UI/src/app/modules/management/components/courses/course-chapters/course-chapters.component.ts index caef457..bdab7cb 100644 --- a/src/UI/src/app/modules/management/components/courses/course-chapters/course-chapters.component.ts +++ b/src/UI/src/app/modules/management/components/courses/course-chapters/course-chapters.component.ts @@ -128,7 +128,7 @@ export class CourseChaptersComponent implements OnInit, OnChanges { description: chapter.description, isFree: chapter.isFree, videoURL: chapter.videoURL, - position: chapter.position, // Keep the original position from the database + // position: chapter.position, // Keep the original position from the database }, ], position: chapter.position, @@ -182,9 +182,6 @@ export class CourseChaptersComponent implements OnInit, OnChanges { // Update item positions after change detection this.updateItemPositions(); - console.log(this.draggableList[0].title + " " + this.draggableList[0].position); - console.log(this.draggableList[1].title + " " + this.draggableList[1].position); - console.log(this.draggableList[2].title + " " + this.draggableList[2].position); this.courseChaptersChange.emit( this.mapDraggableToChapters(this.draggableList) diff --git a/src/UI/src/app/modules/management/components/courses/courses-card/courses-card.component.html b/src/UI/src/app/modules/management/components/courses/courses-card/courses-card.component.html index 7ef9089..0c7be1f 100644 --- a/src/UI/src/app/modules/management/components/courses/courses-card/courses-card.component.html +++ b/src/UI/src/app/modules/management/components/courses/courses-card/courses-card.component.html @@ -8,9 +8,7 @@
{{ course?.title }}
-

- {{ course?.description }} -

+

diff --git a/src/UI/src/app/modules/management/components/shared/course-detail-drawer.component.html b/src/UI/src/app/modules/management/components/shared/course-detail-drawer.component.html new file mode 100644 index 0000000..bf5a19d --- /dev/null +++ b/src/UI/src/app/modules/management/components/shared/course-detail-drawer.component.html @@ -0,0 +1,235 @@ +
+ + + + diff --git a/src/UI/src/app/modules/management/components/shared/course-detail-drawer.component.ts b/src/UI/src/app/modules/management/components/shared/course-detail-drawer.component.ts new file mode 100644 index 0000000..2e9231b --- /dev/null +++ b/src/UI/src/app/modules/management/components/shared/course-detail-drawer.component.ts @@ -0,0 +1,147 @@ +import { CommonModule } from '@angular/common'; +import { + AfterViewInit, + Component, + ElementRef, + HostListener, + Input, + OnInit, + ViewChild, +} from '@angular/core'; +import { Chapter, Course } from '../../models/course'; +import { NgIcon, provideIcons } from '@ng-icons/core'; +import { + heroArrowDownCircle, + heroArrowUpCircle, + heroDocument, + heroHeart, + heroLockClosed, + heroShoppingBag, + heroTv, + heroXCircle, +} from '@ng-icons/heroicons/outline'; +import { heroHeartSolid } from '@ng-icons/heroicons/solid'; +import { FormsModule } from '@angular/forms'; +import { DrawerService } from '../../services/drawer.service'; +import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; + +@Component({ + selector: 'app-detail-drawer', + standalone: true, + imports: [CommonModule, NgIcon, FormsModule], + templateUrl: './course-detail-drawer.component.html', + viewProviders: [ + provideIcons({ + heroArrowDownCircle, + heroArrowUpCircle, + heroHeart, + heroHeartSolid, + heroShoppingBag, + heroXCircle, + heroTv, + heroLockClosed, + heroDocument, + }), + ], +}) +export class CourseDetailDrawer implements OnInit { + handleLikeCourse(arg0: string) { + this.isLiked = !this.isLiked; + } + @ViewChild('drawerElement') drawerElement: ElementRef; + + isDrawerOpen = false; + showFullDescription = false; + isLiked: boolean = false; + course: Course = null; + + constructor( + private sanitizer: DomSanitizer, + private drawerService: DrawerService, + private elementRef: ElementRef, + private senitaizer: DomSanitizer + ) { + this.drawerService.getOpenModalStatus().subscribe((isOpen) => { + this.isDrawerOpen = isOpen; + }); + this.drawerService.getModalData().subscribe((course: Course) => { + this.processCourseData(course); + }); + } + +processCourseData(course: Course): void { + + if (course) { + // Map chapters to a new array with isExpanded property + const chaptersWithExpansion: Chapter[] = course.chapters.map(chapter => ({ + ...chapter, + isExpanded: false + }) as unknown as Chapter); + + // Sort chapters based on their positions in the database + const sortedChapters: Chapter[] = chaptersWithExpansion.sort((a, b) => a.position - b.position); + + // Update the course object with the sorted and expanded chapters + this.course = { ...course, chapters: sortedChapters }; + + } +} + + + toggleAccordion(chapterId: string): void { + // Find the index of the chapter in the array + const index = this.course.chapters.findIndex(chapter => chapter.id === chapterId); + + // findd if the chapter is free or not + const isFree = this.course.chapters[index].isFree; + // Toggle the isExpanded property + if (index !== -1 && isFree) { + this.course.chapters[index]['isExpanded'] = !this.course.chapters[index]['isExpanded']; + } + } + + + + toggleDescription() { + this.showFullDescription = !this.showFullDescription; + } + + @HostListener('document:mousedown', ['$event']) + onGlobalClick(event): void { + const drawerElement = this.drawerElement?.nativeElement; + + // Check if the event target is not the drawer element or its descendants + if ( + event.target !== drawerElement && + !drawerElement?.contains(event.target) + ) { + this.closeDrawer(); + } + } + + closeDrawer() { + this.drawerService.closeModal(); + this.course = null; + this.isDrawerOpen = false; + } + + getVideoEmbedUrl(url: string): any { + // Example YouTube URL formats: + // https://www.youtube.com/watch?v=VIDEO_ID + // https://youtu.be/VIDEO_ID + const videoId = this.extractVideoId(url); + if (videoId) { + const embedUrl = `https://www.youtube.com/embed/${videoId}`; + return this.sanitizer.bypassSecurityTrustResourceUrl(embedUrl); + } + return null; + } + + private extractVideoId(url: string): string | null { + const youtubeRegex = + /(?:youtube\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})/; + const match = url.match(youtubeRegex); + return match ? match[1] : null; + } + ngOnInit(): void {} +} diff --git a/src/UI/src/app/modules/management/models/course.ts b/src/UI/src/app/modules/management/models/course.ts index d1fe1db..770a26d 100644 --- a/src/UI/src/app/modules/management/models/course.ts +++ b/src/UI/src/app/modules/management/models/course.ts @@ -7,6 +7,7 @@ export interface Course { price: number; categories: Categories[]; chapters: Chapter[]; + authorName: string; } export interface Categories { diff --git a/src/UI/src/app/modules/management/pages/user-courses/courses.component.html b/src/UI/src/app/modules/management/pages/user-courses/courses.component.html index e5a53b2..2a1ea09 100644 --- a/src/UI/src/app/modules/management/pages/user-courses/courses.component.html +++ b/src/UI/src/app/modules/management/pages/user-courses/courses.component.html @@ -1,31 +1,153 @@ -
+
- + - -
- -
+ +
+ +
+ + + +
+ +
+
+
+ + + - - -
-
- -
-
+ +
+
+
+
+ +
+ +
+ +
+ +
+
+ + {{ category.name }} + +
+
+
+ +
+

+ {{ course.title }} +

+ +
+
+ Rounded avatar +
+ +
+ {{ course?.authorName}} +
+
+ +
+
+ + 349 +
+ +
+ + {{ + course?.price != 0 ? course?.price + " " + "DKK" : "FREE" + }} + +
+
+
+ + +
+ +
+ +
+ +
+ +
+

No courses found.

+
+
+ +
+ +
+ + diff --git a/src/UI/src/app/modules/management/pages/user-courses/courses.component.ts b/src/UI/src/app/modules/management/pages/user-courses/courses.component.ts index 200b73d..767b337 100644 --- a/src/UI/src/app/modules/management/pages/user-courses/courses.component.ts +++ b/src/UI/src/app/modules/management/pages/user-courses/courses.component.ts @@ -1,10 +1,21 @@ -import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; -import { CommonModule } from '@angular/common'; +import { + Component, + Input, + NgModule, + OnInit, + TemplateRef, + ViewChild, +} from '@angular/core'; +import { CommonModule, NgIf } from '@angular/common'; import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { BoxesHeaderComponent } from '../../components/boxes/boxes-header/boxes-header.component'; import { BoxesTableComponent } from '../../components/boxes/boxes-table/boxes-table.component'; -import { NgxDatatableModule,ColumnMode,DatatableComponent } from '@swimlane/ngx-datatable'; +import { + NgxDatatableModule, + ColumnMode, + DatatableComponent, +} from '@swimlane/ngx-datatable'; import { BoxesModalComponent } from '../../components/boxes/boxes-modal/boxes-modal.component'; import { Box } from '../../models/box'; import { CoursesCardComponent } from '../../components/courses/courses-card/courses-card.component'; @@ -12,30 +23,89 @@ import { CourseService } from '../../services/course-service.service'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { Course } from '../../models/course'; +import { CourseDetailDrawer } from '../../components/shared/course-detail-drawer.component'; +import { DrawerService } from '../../services/drawer.service'; +import { FormsModule } from '@angular/forms'; +import { NgIcon, provideIcons } from '@ng-icons/core'; +import { heroHeart } from '@ng-icons/heroicons/outline'; +import { heroHeartSolid } from '@ng-icons/heroicons/solid'; @Component({ selector: 'app-courses', standalone: true, - imports: [ CommonModule,BoxesHeaderComponent,BoxesTableComponent,NgxDatatableModule,BoxesModalComponent,CoursesCardComponent,NgxSkeletonLoaderModule,RouterLink], + imports: [ + CommonModule, + NgIf, + BoxesHeaderComponent, + BoxesTableComponent, + NgxDatatableModule, + BoxesModalComponent, + CoursesCardComponent, + NgxSkeletonLoaderModule, + RouterLink, + CourseDetailDrawer, + FormsModule, + NgIcon, + ], templateUrl: './courses.component.html', + viewProviders: [provideIcons({ heroHeart, heroHeartSolid })], }) export class CoursesComponent implements OnInit { + isLiked = false; + isLoaded = false; - courses: Course[] = [] + courses: Course[] = []; + isDrawerOpen = false; + + currentOpenCourse: Course = null; + + filteredCourses: Course[] = []; + + @Input() searchQuery: string = ''; - constructor(private courseService: CourseService,private router: Router) { + openDrawer(course: Course) { + this.drawerService.openModal(); + this.drawerService.setModalData(course); + } + + closeDrawer() { + this.isDrawerOpen = false; + this.currentOpenCourse = null; + } + handleLikeCourse(arg0: string) { + // find the course by id and toggle the like + // also hit the endpoint for liking the course SignalR + this.isLiked = !this.isLiked; + } + + constructor( + private courseService: CourseService, + private router: Router, + private drawerService: DrawerService + ) { courseService.getAllCourses().subscribe((data: any) => { this.courses = data.courses; - - this.isLoaded = true; - }) + setTimeout(() => { + this.isLoaded = true; + }, 1000); + + this.filteredCourses = this.courses; + }); + } + + ngOnInit(): void {} + + filterCourses(): void { + this.filteredCourses = this.courses.filter((course) => + course.title.toLowerCase().includes(this.searchQuery.toLowerCase()) + ); } - ngOnInit(): void { - - + onSearchTermChange(searchTerm: string): void { + this.searchQuery = searchTerm; + this.filterCourses(); } diff --git a/src/UI/src/app/modules/management/services/drawer.service.ts b/src/UI/src/app/modules/management/services/drawer.service.ts new file mode 100644 index 0000000..3b8c809 --- /dev/null +++ b/src/UI/src/app/modules/management/services/drawer.service.ts @@ -0,0 +1,43 @@ +import { Injectable } from '@angular/core'; +import { Subject } from 'rxjs'; +import { Course } from '../models/course'; + +@Injectable({ + providedIn: 'root', +}) +export class DrawerService { + private openModalSubject = new Subject(); + private modalDataSubject = new Subject(); + private closeModalSubject = new Subject(); + + openModal() { + this.openModalSubject.next(true); + } + + closeModal() { + this.closeModalSubject.next(false); + this.resetModalData(); + } + + onOpenModal() { + return this.openModalSubject.asObservable(); + } + + onCloseModal() { + return this.closeModalSubject.asObservable(); + } + + getOpenModalStatus() { + return this.openModalSubject.asObservable(); + } + + setModalData(data: Course) { + this.modalDataSubject.next(data); + } + getModalData() { + return this.modalDataSubject.asObservable(); + } + private resetModalData() { + this.modalDataSubject.next(null); + } +} diff --git a/src/UI/src/styles.scss b/src/UI/src/styles.scss index 52d5a54..0a1cbcd 100755 --- a/src/UI/src/styles.scss +++ b/src/UI/src/styles.scss @@ -7,6 +7,10 @@ @import "~@ng-select/ng-select/themes/default.theme.css"; + + + + @layer base { [type='text'], [type='email'], @@ -30,9 +34,13 @@ [type='radio'] { @apply h-4 w-4 rounded border-gray-300 bg-gray-100 text-green-600 focus:ring-2 focus:ring-green-500 dark:border-night-600 dark:bg-night-700 dark:ring-offset-night-800 dark:focus:ring-green-600; } + + + } @layer components { + .dropdown-content { @apply pointer-events-none scale-95 opacity-0 duration-100 ease-in; } diff --git a/src/UI/tailwind.config.js b/src/UI/tailwind.config.js index eac6a36..8acf00d 100755 --- a/src/UI/tailwind.config.js +++ b/src/UI/tailwind.config.js @@ -66,7 +66,7 @@ module.exports = { custom: '0px 0px 50px 0px rgb(82 63 105 / 15%)', }, colors: { - primary: colors.blue, + primary: colors.slate, night: { 50: '#ffffff', /* Lightest shade (white) */ 100: '#ffffff', /* Lighter shade */ diff --git a/src/UI/yarn.lock b/src/UI/yarn.lock index 3582f7d..5f04e63 100644 --- a/src/UI/yarn.lock +++ b/src/UI/yarn.lock @@ -7249,7 +7249,12 @@ symbol-observable@4.0.0: resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz" integrity sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ== -"tailwindcss@^2.0.0 || ^3.0.0", tailwindcss@^3.3.5, "tailwindcss@>=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1", "tailwindcss@>=3.0.0 || >= 3.0.0-alpha.1", "tailwindcss@>=3.0.0 || insiders": +tailwindcss-animated@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/tailwindcss-animated/-/tailwindcss-animated-1.0.1.tgz" + integrity sha512-u5wusj89ZwP8I+s8WZlaAd7aZTWBN/XEG6QgMKpkIKmAf3xP1A6WYf7oYIKmGaB10UAQaSqWopi/i1ozzZEs8Q== + +"tailwindcss@^2.0.0 || ^3.0.0", tailwindcss@^3.3.5, "tailwindcss@>=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1", "tailwindcss@>=3.0.0 || >= 3.0.0-alpha.1", "tailwindcss@>=3.0.0 || insiders", tailwindcss@>=3.1.0: version "3.3.5" resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.5.tgz" integrity sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA== diff --git a/src/Web/wwwroot/api/specification.json b/src/Web/wwwroot/api/specification.json index cbc8f9a..6857789 100644 --- a/src/Web/wwwroot/api/specification.json +++ b/src/Web/wwwroot/api/specification.json @@ -735,6 +735,10 @@ "items": { "$ref": "#/components/schemas/ChapterDto" } + }, + "authorName": { + "type": "string", + "nullable": true } } },