0" class="category">
+
+ @if (favoriteMovies.length > 0) {
+
Favorites
-
-
- @for (favorite of favoriteMovies; track favorite) {
-
- @for (movie of movies; track movie) {
-
- @if (movie.id === favorite) {
-
-
![]()
-
- } } }
-
-
-
-
-
-
+
+ }
+
@for (filmGenre of filmGenres; track filmGenre) {
-
+
@if (allMovies(filmGenre.code).length > 0) {
{{ filmGenre.name }}
-
-
- @for (movie of allMovies(filmGenre.code); track movie) {
-
-
-
-
![]()
-
- @if (watchedMovies.includes(movie.id)) {
-
-

-
- }
-
- }
-
-
-
-
-
-
+
} }
+}
diff --git a/frontend/src/app/components/home/browse/categories/categories.component.scss b/frontend/src/app/components/home/browse/categories/categories.component.scss
index 4066b26..a143806 100644
--- a/frontend/src/app/components/home/browse/categories/categories.component.scss
+++ b/frontend/src/app/components/home/browse/categories/categories.component.scss
@@ -16,103 +16,6 @@ section {
}
}
-// Movies
-
-.movie {
- position: relative;
- width: 213px;
- height: 120px;
- padding: 6px;
- .banner {
- img {
- width: 213px;
- height: 120px;
- transition: scale 300ms ease-in-out;
- border: 2px solid rgba($black, 0);
- cursor: pointer;
- &:hover {
- scale: 1.02;
- border: 2px solid $blue;
- }
- }
- }
- .watched {
- position: absolute;
- top: 15px;
- right: 15px;
- z-index: 2;
- img {
- width: 24px;
- height: auto;
- filter: brightness(0) saturate(100%) invert(100%) sepia(28%) saturate(1%)
- hue-rotate(288deg) brightness(101%) contrast(101%)
- drop-shadow(0 0 5px rgba(38, 143, 255, 1));
- }
- }
-}
-
-.selected {
- border: 2px solid $blue !important;
-}
-
-.movies {
- display: flex;
- overflow-x: auto;
- overflow-y: hidden;
- -ms-overflow-style: none;
- scrollbar-width: none;
- padding: 0 24x;
-}
-
-.movies::-webkit-scrollbar {
- display: none;
-}
-
-// Scroll buttons
-
-.scroll-buttons {
- position: absolute;
- top: 50%;
- width: 100%;
- display: none;
- justify-content: space-between;
- pointer-events: none;
- transform: translateY(-50%);
-}
-
-.scroll-buttons.show {
- display: flex;
-}
-
-.scroll-left,
-.scroll-right {
- background: url("./../../../../../assets/img/arrow_forward.svg") no-repeat
- center;
- background-size: 20px 30px;
- border: none;
- width: 40px;
- height: 40px;
- cursor: pointer;
- pointer-events: auto;
- &:hover {
- transition: 125ms ease-in-out;
- filter: brightness(0) saturate(100%) invert(26%) sepia(77%) saturate(2342%)
- hue-rotate(228deg) brightness(83%) contrast(115%);
- }
-}
-
-.scroll-left {
- position: absolute;
- left: -32px;
- background-image: url("./../../../../../assets/img/arrow_back.svg");
-}
-
-.scroll-right {
- position: absolute;
- right: -38px;
- background-image: url("./../../../../../assets/img/arrow_forward.svg");
-}
-
// Hide scrollbar
.hide-scrollbar {
@@ -130,12 +33,6 @@ section {
/*------------- RESPONSIVE -------------*/
-@media screen and (max-width: 600px) {
- .hide-scrollbar {
- height: calc(100% - 120px);
- }
-}
-
@media screen and (max-width: 400px) {
.category {
p {
@@ -144,3 +41,13 @@ section {
}
}
}
+
+@media screen and (max-width: 600px) {
+ section {
+ margin: 0 12px;
+ }
+
+ .hide-scrollbar {
+ height: calc(100% - 120px);
+ }
+}
diff --git a/frontend/src/app/components/home/browse/categories/categories.component.ts b/frontend/src/app/components/home/browse/categories/categories.component.ts
index 0fbd051..9a04e2d 100644
--- a/frontend/src/app/components/home/browse/categories/categories.component.ts
+++ b/frontend/src/app/components/home/browse/categories/categories.component.ts
@@ -8,11 +8,12 @@ import {
Output,
} from '@angular/core';
import { environment } from '../../../../../environments/environment';
+import { MoviesListComponent } from './movie-list/movie-list.component';
@Component({
selector: 'app-categories',
standalone: true,
- imports: [CommonModule],
+ imports: [CommonModule, MoviesListComponent],
templateUrl: './categories.component.html',
styleUrl: './categories.component.scss',
})
@@ -47,6 +48,12 @@ export class CategoriesComponent implements AfterViewInit {
{ code: 'western', name: 'Western' },
];
+ getFavoriteMovies() {
+ return this.movies.filter((movie) =>
+ this.favoriteMovies.includes(movie.id)
+ );
+ }
+
ngAfterViewInit() {
this.checkScroll();
}
diff --git a/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.html b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.html
new file mode 100644
index 0000000..5a6b3b4
--- /dev/null
+++ b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.html
@@ -0,0 +1,33 @@
+
+
+ @for (movie of movies; track movie) {
+
+
+
![]()
+
+
+

+
+
+ }
+
+
+
+
diff --git a/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.scss b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.scss
new file mode 100644
index 0000000..c9e6404
--- /dev/null
+++ b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.scss
@@ -0,0 +1,99 @@
+@use "./../../../../../../assets/style/colors.scss" as *;
+
+.movies {
+ display: flex;
+ overflow-x: auto;
+ overflow-y: hidden;
+ -ms-overflow-style: none;
+ scrollbar-width: none;
+ padding-bottom: 24px;
+}
+
+.movies::-webkit-scrollbar {
+ display: none;
+}
+
+.movie {
+ position: relative;
+ width: 213px;
+ height: 120px;
+ padding: 6px;
+ .banner {
+ img {
+ width: 213px;
+ height: 120px;
+ transition: scale 300ms ease-in-out;
+ border: 2px solid rgba($black, 0);
+ cursor: pointer;
+ &:hover {
+ scale: 1.02;
+ border: 2px solid $blue;
+ }
+ }
+ }
+ .watched {
+ position: absolute;
+ top: 15px;
+ right: 15px;
+ z-index: 2;
+ img {
+ width: 24px;
+ height: auto;
+ filter: brightness(0) saturate(100%) invert(100%) sepia(28%) saturate(1%)
+ hue-rotate(288deg) brightness(101%) contrast(101%)
+ drop-shadow(0 0 5px rgba(38, 143, 255, 1));
+ }
+ }
+}
+
+.selected {
+ border: 2px solid $blue !important;
+}
+
+// Scroll buttons
+
+.scroll-buttons {
+ position: absolute;
+ top: 50%;
+ width: 100%;
+ display: none;
+ justify-content: space-between;
+ pointer-events: none;
+ transform: translateY(-50%);
+}
+
+.scroll-buttons.show {
+ display: flex;
+}
+
+.scroll-left,
+.scroll-right {
+ position: absolute;
+ background-size: 20px 30px;
+ border: none;
+ width: 40px;
+ height: 40px;
+ cursor: pointer;
+ pointer-events: auto;
+ &:hover {
+ transition: 125ms ease-in-out;
+ filter: brightness(0) saturate(100%) invert(26%) sepia(77%) saturate(2342%)
+ hue-rotate(228deg) brightness(83%) contrast(115%);
+ }
+}
+
+.scroll-left {
+ left: -25px;
+}
+
+.scroll-right {
+ right: -25px;
+}
+
+/*------------- RESPONSIVE -------------*/
+
+@media screen and (max-width: 600px) {
+ .hide-scrollbar {
+ height: calc(100% - 120px);
+ }
+}
diff --git a/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.spec.ts b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.spec.ts
new file mode 100644
index 0000000..8edebd7
--- /dev/null
+++ b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.spec.ts
@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { MoviesListComponent } from './movie-list.component';
+
+describe('MoviesListComponent', () => {
+ let component: MoviesListComponent;
+ let fixture: ComponentFixture
;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [MoviesListComponent],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(MoviesListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.ts b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.ts
new file mode 100644
index 0000000..50809f2
--- /dev/null
+++ b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.ts
@@ -0,0 +1,47 @@
+import { Component, Input, Output, EventEmitter } from '@angular/core';
+import { environment } from '../../../../../../environments/environment';
+import { CommonModule } from '@angular/common';
+
+@Component({
+ selector: 'app-movie-list',
+ standalone: true,
+ imports: [CommonModule],
+ templateUrl: './movie-list.component.html',
+ styleUrls: ['./movie-list.component.scss'],
+})
+export class MoviesListComponent {
+ @Input() movies: any[] = [];
+ @Input() currentMovie: number = 0;
+ @Input() watchedMovies: any[] = [];
+ @Input() movieCategory: string = '';
+ @Output() currentMovieId = new EventEmitter();
+
+ getThumbnailUrl(movieId: number, fileName: string): string {
+ return `${environment.baseUrl}/media/thumbnails/${movieId}/${fileName}_480p.jpg`;
+ }
+
+ openCurrentMovie(movieId: number) {
+ this.currentMovie = movieId;
+ this.currentMovieId.emit(movieId);
+ }
+
+ scrollLeft(event: MouseEvent) {
+ const button = event.target as HTMLElement;
+ const container = button
+ .closest('.category')
+ ?.querySelector('.movies') as HTMLElement;
+ if (container) {
+ container.scrollLeft -= 217;
+ }
+ }
+
+ scrollRight(event: MouseEvent) {
+ const button = event.target as HTMLElement;
+ const container = button
+ .closest('.category')
+ ?.querySelector('.movies') as HTMLElement;
+ if (container) {
+ container.scrollLeft += 217;
+ }
+ }
+}
diff --git a/frontend/src/app/components/home/browse/hero-banner/hero-banner.component.html b/frontend/src/app/components/home/browse/hero-banner/hero-banner.component.html
index c3a6f4a..d829c44 100644
--- a/frontend/src/app/components/home/browse/hero-banner/hero-banner.component.html
+++ b/frontend/src/app/components/home/browse/hero-banner/hero-banner.component.html
@@ -1,12 +1,12 @@
@@ -30,21 +30,21 @@
{{ currentMovie[0].title }}
{{ currentMovie[0].description }}