From c710dd923a89c7b9ff1f2f84f1fb3d9c7717a5a1 Mon Sep 17 00:00:00 2001 From: Maksym Diachuk Date: Mon, 1 Dec 2025 16:28:21 +0200 Subject: [PATCH 1/2] Integrate with keycloak. Introduce Google OIDC auth --- apiGateway/src/main/resources/application.yml | 2 +- book-bazaar/package-lock.json | 29 +++++ book-bazaar/package.json | 2 + book-bazaar/public/silent-check-sso.html | 8 ++ book-bazaar/src/app/app.config.ts | 41 +++++- .../src/app/components/header/header.html | 42 +++++- .../src/app/components/header/header.ts | 17 ++- .../src/app/services/user/userService.ts | 72 +++++++++++ .../src/main/resources/application-dev.yml | 2 +- docker-compose.yml | 9 ++ infrastructure/keycloak/e-library-realm.json | 120 +++++++++++++----- 11 files changed, 298 insertions(+), 46 deletions(-) create mode 100644 book-bazaar/public/silent-check-sso.html create mode 100644 book-bazaar/src/app/services/user/userService.ts diff --git a/apiGateway/src/main/resources/application.yml b/apiGateway/src/main/resources/application.yml index c041e40..1c1e6ae 100644 --- a/apiGateway/src/main/resources/application.yml +++ b/apiGateway/src/main/resources/application.yml @@ -7,7 +7,7 @@ spring: oauth2: resourceserver: jwt: - issuer-uri: http://keycloak:8080/realms/e-library + issuer-uri: http://localhost:8181/realms/e-library jwk-set-uri: http://localhost:8181/realms/e-library/protocol/openid-connect/certs services: diff --git a/book-bazaar/package-lock.json b/book-bazaar/package-lock.json index d881649..f61482b 100644 --- a/book-bazaar/package-lock.json +++ b/book-bazaar/package-lock.json @@ -17,6 +17,8 @@ "@angular/platform-browser": "^20.3.0", "@angular/router": "^20.3.0", "@tailwindcss/postcss": "^4.1.16", + "keycloak-angular": "^20.0.0", + "keycloak-js": "^26.2.1", "rxjs": "~7.8.0", "tslib": "^2.3.0" }, @@ -639,6 +641,7 @@ "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.10.tgz", "integrity": "sha512-Z03cfH1jgQ7XMDJj4R8qAGqivcvhdG3wYBwaiN1K1ODBgPhbFKNeD4stKqYp7xBNtswmM2O2jMxrL/Djwju4Gg==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -6859,6 +6862,32 @@ "node": ">=10" } }, + "node_modules/keycloak-angular": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/keycloak-angular/-/keycloak-angular-20.0.0.tgz", + "integrity": "sha512-p9ThVUN8TNz15M2dd11VRDdHzgEDRSSxvyRGtK4N45lTbfs52DeNK+YXcpgt8ZX0/YN27GjU9GjiB4odI4/A2Q==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.1" + }, + "peerDependencies": { + "@angular/common": "^20", + "@angular/core": "^20", + "@angular/router": "^20", + "keycloak-js": "^18 || ^19 || ^20 || ^21 || ^22 || ^23 || ^24 || ^25 || ^26", + "rxjs": "^7" + } + }, + "node_modules/keycloak-js": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-26.2.1.tgz", + "integrity": "sha512-bZt6fQj/TLBAmivXSxSlqAJxBx/knNZDQGJIW4ensGYGN4N6tUKV8Zj3Y7/LOV8eIpvWsvqV70fbACihK8Ze0Q==", + "license": "Apache-2.0", + "peer": true, + "workspaces": [ + "test" + ] + }, "node_modules/lightningcss": { "version": "1.30.2", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", diff --git a/book-bazaar/package.json b/book-bazaar/package.json index fe2ae82..5488764 100644 --- a/book-bazaar/package.json +++ b/book-bazaar/package.json @@ -31,6 +31,8 @@ "@angular/platform-browser": "^20.3.0", "@angular/router": "^20.3.0", "@tailwindcss/postcss": "^4.1.16", + "keycloak-angular": "^20.0.0", + "keycloak-js": "^26.2.1", "rxjs": "~7.8.0", "tslib": "^2.3.0" }, diff --git a/book-bazaar/public/silent-check-sso.html b/book-bazaar/public/silent-check-sso.html new file mode 100644 index 0000000..96b3cf9 --- /dev/null +++ b/book-bazaar/public/silent-check-sso.html @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/book-bazaar/src/app/app.config.ts b/book-bazaar/src/app/app.config.ts index a4001de..f5b4220 100644 --- a/book-bazaar/src/app/app.config.ts +++ b/book-bazaar/src/app/app.config.ts @@ -1,14 +1,47 @@ -import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZonelessChangeDetection } from '@angular/core'; -import {provideRouter, withViewTransitions} from '@angular/router'; +import { ApplicationConfig, inject, provideAppInitializer, provideBrowserGlobalErrorListeners, provideZonelessChangeDetection } from '@angular/core'; +import { provideRouter, withViewTransitions } from '@angular/router'; import { routes } from './app.routes'; -import { provideHttpClient } from '@angular/common/http'; +import { provideHttpClient, withInterceptors } from '@angular/common/http'; +import { + provideKeycloak, + INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG, + includeBearerTokenInterceptor, + createInterceptorCondition +} from 'keycloak-angular'; export const appConfig: ApplicationConfig = { providers: [ provideBrowserGlobalErrorListeners(), provideZonelessChangeDetection(), provideRouter(routes, withViewTransitions()), - provideHttpClient(), + + provideHttpClient(withInterceptors([includeBearerTokenInterceptor])), + + provideKeycloak({ + config: { + url: 'http://localhost:8181', + realm: 'e-library', + clientId: 'e-library-client' + }, + initOptions: { + // 'check-sso': перевіряє сесію тихо. Якщо юзер залогінений - пускає, ні - лишає анонімом. + // 'login-required': відразу кидає на сторінку логіну (вам це НЕ підходить). + onLoad: 'check-sso', + silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html', + checkLoginIframe: false // Вимикаємо, щоб уникнути проблем з cookies у сучасних браузерах + }, + // Автоматично додавати токен (Bearer) до запитів + }), + { + provide: INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG, + useValue: [ + createInterceptorCondition({ + urlPattern: /^(http:\/\/localhost:9000|http:\/\/localhost:8080)(\/.*)?$/i, // Регулярка для ваших сервісів + bearerPrefix: 'Bearer' + }), + // Можна додати інші умови, якщо є інші бекенди + ] + } ] }; diff --git a/book-bazaar/src/app/components/header/header.html b/book-bazaar/src/app/components/header/header.html index 4957c8e..b3dba3e 100644 --- a/book-bazaar/src/app/components/header/header.html +++ b/book-bazaar/src/app/components/header/header.html @@ -1,15 +1,45 @@ -
-
+
+
- + @if (userService.isLoggedIn()) { + + + + + + + + } @else { +
+ + +
+ }
-
+
\ No newline at end of file diff --git a/book-bazaar/src/app/components/header/header.ts b/book-bazaar/src/app/components/header/header.ts index fa99e20..556e25d 100644 --- a/book-bazaar/src/app/components/header/header.ts +++ b/book-bazaar/src/app/components/header/header.ts @@ -1,17 +1,24 @@ -import { Component } from '@angular/core'; +import { Component, inject, signal } from '@angular/core'; import {MatButton} from '@angular/material/button'; import {RouterLink} from '@angular/router'; +import { KeycloakProfile } from 'keycloak-js'; +import { MatIcon } from '@angular/material/icon'; +import { MatMenuModule } from '@angular/material/menu'; +import Keycloak from 'keycloak-js'; +import { UserService } from '../../services/user/userService'; @Component({ selector: 'app-header', imports: [ MatButton, - RouterLink - - ], + RouterLink, + MatIcon, + MatMenuModule +], templateUrl: './header.html', styleUrl: './header.css', }) export class Header { - + protected userService = inject(UserService); } + diff --git a/book-bazaar/src/app/services/user/userService.ts b/book-bazaar/src/app/services/user/userService.ts new file mode 100644 index 0000000..7681c08 --- /dev/null +++ b/book-bazaar/src/app/services/user/userService.ts @@ -0,0 +1,72 @@ +import { inject, Injectable, signal, computed } from '@angular/core'; +import Keycloak from 'keycloak-js'; // Імпорт класу/типу +import { KeycloakProfile } from 'keycloak-js'; + +@Injectable({ + providedIn: 'root' +}) +export class UserService { + // Інжектимо інстанс Keycloak + private keycloak = inject(Keycloak); + + private userProfileSignal = signal(null); + + // Використовуємо .authenticated для початкового стану + // На момент створення сервісу Keycloak вже ініціалізований! + isLoggedIn = signal(!!this.keycloak.authenticated); + + userProfile = this.userProfileSignal.asReadonly(); + + avatarUrl = computed(() => { + const token = this.keycloak.idTokenParsed as any; + if (token && token.picture) { + console.log(token.picture) + return token.picture; + } + + // 2. Якщо в токені немає, пробуємо через профіль (резервний варіант) + const profile = this.userProfileSignal(); + if (!profile) return null; + + // Перевірка на attributes (безпечний доступ) + const attrs = (profile as any).attributes; + if (attrs && attrs.picture && attrs.picture.length > 0) { + return attrs.picture[0]; + } + + return null; + }); + + userName = computed(() => { + const p = this.userProfileSignal(); + return p ? `${p.firstName}` : ''; + }); + + constructor() { + // Якщо юзер залогінений - одразу вантажимо профіль + if (this.isLoggedIn()) { + this.loadProfile(); + } + } + + private async loadProfile() { + try { + const profile = await this.keycloak.loadUserProfile(); + this.userProfileSignal.set(profile); + } catch (e) { + console.error('Error loading profile', e); + } + } + + login() { + this.keycloak.login(); + } + + logout() { + this.keycloak.logout(); + } + + register() { + this.keycloak.register(); + } +} \ No newline at end of file diff --git a/bookService/src/main/resources/application-dev.yml b/bookService/src/main/resources/application-dev.yml index eb6e1fe..33e1cce 100644 --- a/bookService/src/main/resources/application-dev.yml +++ b/bookService/src/main/resources/application-dev.yml @@ -16,7 +16,7 @@ spring: oauth2: resourceserver: jwt: - issuer-uri: http://keycloak:8080/realms/e-library + issuer-uri: http://localhost:8181/realms/e-library jwk-set-uri: http://localhost:8181/realms/e-library/protocol/openid-connect/certs token-uri: http://localhost:8181/realms/e-library/protocol/openid-connect/token diff --git a/docker-compose.yml b/docker-compose.yml index 264f1bb..d791088 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -155,6 +155,15 @@ services: - ./infrastructure/grafana/datasource.yml:/etc/grafana/provisioning/datasources/datasource.yml networks: - e-library-network + + mailhog: + image: mailhog/mailhog + container_name: mailhog + ports: + - "1025:1025" + - "8025:8025" + networks: + - e-library-network networks: e-library-network: volumes: diff --git a/infrastructure/keycloak/e-library-realm.json b/infrastructure/keycloak/e-library-realm.json index c140bda..534ee12 100644 --- a/infrastructure/keycloak/e-library-realm.json +++ b/infrastructure/keycloak/e-library-realm.json @@ -1,8 +1,8 @@ { "id": "ca3af2c9-0567-4620-8bf2-2f17a29c793f", "realm": "e-library", - "displayName": "", - "displayNameHtml": "", + "displayName": "BookBazaar", + "displayNameHtml": "BookBazaar", "notBefore": 0, "defaultSignatureAlgorithm": "RS256", "revokeRefreshToken": false, @@ -31,11 +31,11 @@ "sslRequired": "external", "registrationAllowed": true, "registrationEmailAsUsername": false, - "rememberMe": false, - "verifyEmail": false, + "rememberMe": true, + "verifyEmail": true, "loginWithEmailAllowed": true, "duplicateEmailsAllowed": false, - "resetPasswordAllowed": false, + "resetPasswordAllowed": true, "editUsernameAllowed": false, "bruteForceProtected": false, "permanentLockout": false, @@ -633,7 +633,9 @@ "publicClient": true, "frontchannelLogout": false, "protocol": "openid-connect", - "attributes": {}, + "attributes": { + "post.logout.redirect.uris": "+" + }, "authenticationFlowBindingOverrides": {}, "fullScopeAllowed": false, "nodeReRegistrationTimeout": 0, @@ -671,7 +673,9 @@ "publicClient": false, "frontchannelLogout": false, "protocol": "openid-connect", - "attributes": {}, + "attributes": { + "post.logout.redirect.uris": "+" + }, "authenticationFlowBindingOverrides": {}, "fullScopeAllowed": false, "nodeReRegistrationTimeout": 0, @@ -694,16 +698,15 @@ "clientId": "e-library-client", "name": "User auth client", "description": "Client for authenticating users ", - "rootUrl": "http://localhost:9000", + "rootUrl": "http://localhost:4200/", "adminUrl": "", - "baseUrl": "http://localhost:9000", + "baseUrl": "http://localhost:4200/", "surrogateAuthRequired": false, "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", - "secret": "**********", "redirectUris": [ - "http://localhost:9000/*" + "http://localhost:4200/*" ], "webOrigins": [ "", @@ -714,15 +717,16 @@ "consentRequired": false, "standardFlowEnabled": true, "implicitFlowEnabled": false, - "directAccessGrantsEnabled": true, + "directAccessGrantsEnabled": false, "serviceAccountsEnabled": false, - "publicClient": false, + "publicClient": true, "frontchannelLogout": true, "protocol": "openid-connect", "attributes": { "oidc.ciba.grant.enabled": "false", "client.secret.creation.time": "1747844036", "backchannel.logout.session.required": "true", + "post.logout.redirect.uris": "+", "display.on.consent.screen": "false", "oauth2.device.authorization.grant.enabled": "false", "backchannel.logout.revoke.offline.tokens": "false" @@ -740,6 +744,7 @@ "config": { "user.session.note": "clientAddress", "introspection.token.claim": "true", + "userinfo.token.claim": "true", "id.token.claim": "true", "access.token.claim": "true", "claim.name": "clientAddress", @@ -755,6 +760,7 @@ "config": { "user.session.note": "clientHost", "introspection.token.claim": "true", + "userinfo.token.claim": "true", "id.token.claim": "true", "access.token.claim": "true", "claim.name": "clientHost", @@ -770,6 +776,7 @@ "config": { "user.session.note": "client_id", "introspection.token.claim": "true", + "userinfo.token.claim": "true", "id.token.claim": "true", "access.token.claim": "true", "claim.name": "client_id", @@ -824,6 +831,7 @@ "oidc.ciba.grant.enabled": "false", "client.secret.creation.time": "1741173352", "backchannel.logout.session.required": "true", + "post.logout.redirect.uris": "+", "display.on.consent.screen": "false", "oauth2.device.authorization.grant.enabled": "false", "backchannel.logout.revoke.offline.tokens": "false" @@ -841,6 +849,7 @@ "config": { "user.session.note": "clientAddress", "introspection.token.claim": "true", + "userinfo.token.claim": "true", "id.token.claim": "true", "access.token.claim": "true", "claim.name": "clientAddress", @@ -856,6 +865,7 @@ "config": { "user.session.note": "clientHost", "introspection.token.claim": "true", + "userinfo.token.claim": "true", "id.token.claim": "true", "access.token.claim": "true", "claim.name": "clientHost", @@ -871,6 +881,7 @@ "config": { "user.session.note": "client_id", "introspection.token.claim": "true", + "userinfo.token.claim": "true", "id.token.claim": "true", "access.token.claim": "true", "claim.name": "client_id", @@ -912,7 +923,9 @@ "publicClient": false, "frontchannelLogout": false, "protocol": "openid-connect", - "attributes": {}, + "attributes": { + "post.logout.redirect.uris": "+" + }, "authenticationFlowBindingOverrides": {}, "fullScopeAllowed": false, "nodeReRegistrationTimeout": 0, @@ -1390,7 +1403,8 @@ "config": { "id.token.claim": "true", "access.token.claim": "true", - "introspection.token.claim": "true" + "introspection.token.claim": "true", + "userinfo.token.claim": "true" } } ] @@ -1507,6 +1521,7 @@ "config": { "introspection.token.claim": "true", "multivalued": "true", + "userinfo.token.claim": "true", "user.attribute": "foo", "id.token.claim": "true", "access.token.claim": "true", @@ -1575,7 +1590,20 @@ "xXSSProtection": "1; mode=block", "strictTransportSecurity": "max-age=31536000; includeSubDomains" }, - "smtpServer": {}, + "smtpServer": { + "replyToDisplayName": "", + "starttls": "false", + "auth": "false", + "envelopeFrom": "", + "ssl": "false", + "password": "**********", + "port": "1025", + "host": "mailhog", + "replyTo": "", + "from": "noreply@bookbazaar.com", + "fromDisplayName": "BookBazaar", + "user": "" + }, "eventsEnabled": false, "eventsListeners": [ "jboss-logging" @@ -1583,8 +1611,42 @@ "enabledEventTypes": [], "adminEventsEnabled": false, "adminEventsDetailsEnabled": false, - "identityProviders": [], - "identityProviderMappers": [], + "identityProviders": [ + { + "alias": "google", + "internalId": "e071f5d5-1110-49a1-81a8-4bb4cb96e312", + "providerId": "google", + "enabled": true, + "updateProfileFirstLoginMode": "on", + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "config": { + "hideOnLoginPage": "false", + "acceptsPromptNoneForwardFromClient": "false", + "clientId": "705636113946-ptom90qg910tp11edh5pl2si9i5su1gl.apps.googleusercontent.com", + "disableUserInfo": "false", + "filteredByClaim": "false", + "syncMode": "IMPORT", + "clientSecret": "**********" + } + } + ], + "identityProviderMappers": [ + { + "id": "9d3d8869-aff3-4392-99df-42cecaa0fed6", + "name": "google-avatar", + "identityProviderAlias": "google", + "identityProviderMapper": "google-user-attribute-mapper", + "config": { + "syncMode": "IMPORT", + "jsonField": "picture", + "userAttribute": "picture" + } + } + ], "components": { "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ { @@ -1663,13 +1725,13 @@ "config": { "allowed-protocol-mapper-types": [ "saml-user-property-mapper", - "saml-role-list-mapper", - "oidc-address-mapper", - "oidc-usermodel-property-mapper", - "oidc-usermodel-attribute-mapper", + "oidc-full-name-mapper", "saml-user-attribute-mapper", + "saml-role-list-mapper", "oidc-sha256-pairwise-sub-mapper", - "oidc-full-name-mapper" + "oidc-usermodel-attribute-mapper", + "oidc-address-mapper", + "oidc-usermodel-property-mapper" ] } }, @@ -1681,14 +1743,14 @@ "subComponents": {}, "config": { "allowed-protocol-mapper-types": [ - "saml-user-attribute-mapper", + "oidc-full-name-mapper", "oidc-address-mapper", - "oidc-usermodel-attribute-mapper", + "saml-user-attribute-mapper", "saml-user-property-mapper", + "oidc-usermodel-attribute-mapper", "oidc-usermodel-property-mapper", - "oidc-full-name-mapper", - "saml-role-list-mapper", - "oidc-sha256-pairwise-sub-mapper" + "oidc-sha256-pairwise-sub-mapper", + "saml-role-list-mapper" ] } } @@ -2397,7 +2459,7 @@ "oauth2DeviceCodeLifespan": "600", "parRequestUriLifespan": "60", "clientSessionMaxLifespan": "0", - "frontendUrl": "http://keycloak:8080", + "frontendUrl": "", "acr.loa.map": "{}" }, "keycloakVersion": "24.0.1", From 6a03136b620df39a5ecbcbbfd27b1dee98323533 Mon Sep 17 00:00:00 2001 From: Maksym Diachuk Date: Mon, 1 Dec 2025 20:11:53 +0200 Subject: [PATCH 2/2] Update styling --- .../public/hero-books-illustration.jpg | Bin 0 -> 56681 bytes .../app/components/book-card/book-card.html | 44 ++++--- .../src/app/components/book-card/book-card.ts | 3 +- .../components/filter-panel/filter-panel.css | 10 ++ .../components/filter-panel/filter-panel.html | 79 ++++++++---- .../components/filter-panel/filter-panel.ts | 11 +- book-bazaar/src/app/components/home/home.html | 93 ++++++++++---- book-bazaar/src/app/components/home/home.ts | 2 +- .../components/search-books/search-books.html | 119 +++++++++++------- .../components/search-books/search-books.ts | 8 +- book-bazaar/src/styles.css | 11 ++ 11 files changed, 259 insertions(+), 121 deletions(-) create mode 100644 book-bazaar/public/hero-books-illustration.jpg diff --git a/book-bazaar/public/hero-books-illustration.jpg b/book-bazaar/public/hero-books-illustration.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0037619bedf147c3376c71e80dcfd9b30aca595d GIT binary patch literal 56681 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 cO4kiEM +
- + -
- +
-
- +
+ {{ book().title }} - + {{ book().author?.name }} -
- +
+ + @if(book().price) { +
+ {{ book().price | currency }} +
+ } + +
@if(book().category) { - {{ book().category?.name }} - + } - @for (genre of book().bookGenres; track genre.id) { - {{ genre.name }} - + } - +
diff --git a/book-bazaar/src/app/components/book-card/book-card.ts b/book-bazaar/src/app/components/book-card/book-card.ts index 24052b7..73ac458 100644 --- a/book-bazaar/src/app/components/book-card/book-card.ts +++ b/book-bazaar/src/app/components/book-card/book-card.ts @@ -6,10 +6,11 @@ import { MatChipSet, MatChip } from "@angular/material/chips"; import { MatTooltipModule } from '@angular/material/tooltip'; import { Category } from '../../model/category'; import { Genre } from '../../model/genre'; +import { CurrencyPipe } from '@angular/common'; @Component({ selector: 'app-book-card', - imports: [MatCard, RouterModule, MatCardTitleGroup, MatCardTitle, MatCardSubtitle, MatChipSet, MatChip, MatTooltipModule], + imports: [MatCard, RouterModule, MatCardTitleGroup, MatCardTitle, MatCardSubtitle, MatChipSet, MatChip, MatTooltipModule, CurrencyPipe], templateUrl: './book-card.html', styleUrl: './book-card.css', }) diff --git a/book-bazaar/src/app/components/filter-panel/filter-panel.css b/book-bazaar/src/app/components/filter-panel/filter-panel.css index 8ca6c9c..015e905 100644 --- a/book-bazaar/src/app/components/filter-panel/filter-panel.css +++ b/book-bazaar/src/app/components/filter-panel/filter-panel.css @@ -20,4 +20,14 @@ .custom-scrollbar { scrollbar-width: thin; scrollbar-color: #e5e7eb transparent; +} + +/* Зменшуємо відступи у чекбоксів, щоб вони виглядали компактніше */ +::ng-deep .mat-mdc-checkbox .mdc-form-field { + padding-right: 0 !important; +} + +::ng-deep .mat-mdc-checkbox-touch-target { + width: 32px !important; + height: 32px !important; } \ No newline at end of file diff --git a/book-bazaar/src/app/components/filter-panel/filter-panel.html b/book-bazaar/src/app/components/filter-panel/filter-panel.html index 8243011..9e2c707 100644 --- a/book-bazaar/src/app/components/filter-panel/filter-panel.html +++ b/book-bazaar/src/app/components/filter-panel/filter-panel.html @@ -1,33 +1,60 @@ -
+
-

Filters

- +
+

+ tune + Filters +

+ @if (hasSelectedFilters()) { + + }
- @for (filter of filters(); track filter.name) { -

{{ filter.label }}

+
+ @for (filter of filters(); track filter.name) { +
+ +

+ {{ filter.label }} + + {{ filter.options.length }} + +

+ +
+ @for (option of visibleOptions(filter); track option) { + + } +
-
- @for (option of visibleOptions(filter); track option) { - + @if (filter.options.length > filter.defaultVisibleCount) { + }
- - -
- } + } +
\ No newline at end of file diff --git a/book-bazaar/src/app/components/filter-panel/filter-panel.ts b/book-bazaar/src/app/components/filter-panel/filter-panel.ts index 985bd5c..3a54a8e 100644 --- a/book-bazaar/src/app/components/filter-panel/filter-panel.ts +++ b/book-bazaar/src/app/components/filter-panel/filter-panel.ts @@ -1,15 +1,17 @@ -import { Component, effect, input, output, signal, SimpleChange, SimpleChanges } from '@angular/core'; +import { Component, computed, effect, input, output, signal, SimpleChange, SimpleChanges } from '@angular/core'; import {Filter} from '../../utils/filter'; import {NgIf} from '@angular/common'; import {MatCheckbox} from '@angular/material/checkbox'; import {MatButton} from '@angular/material/button'; +import { MatIcon } from '@angular/material/icon'; @Component({ selector: 'app-filter-panel', imports: [ NgIf, MatCheckbox, - MatButton + MatButton, + MatIcon ], templateUrl: './filter-panel.html', styleUrl: './filter-panel.css', @@ -24,6 +26,11 @@ export class FilterPanel { changed = output>(); + hasSelectedFilters = computed(() => { + const selected = this.currentSelected(); + return Object.values(selected).some(arr => arr && arr.length > 0); + }); + constructor() { effect(() => { if (this.selectedFilters) { diff --git a/book-bazaar/src/app/components/home/home.html b/book-bazaar/src/app/components/home/home.html index 23c5ee0..d724614 100644 --- a/book-bazaar/src/app/components/home/home.html +++ b/book-bazaar/src/app/components/home/home.html @@ -1,28 +1,75 @@
-
-
-

Discover Your Next Great Read

-

Explore thousands of books, read reviews, and connect with fellow book - lovers in our digital library.

-
-
- - - -
+
+
+ +
+
+

+ Discover Your + Next Great Read +

+ +

+ Explore thousands of books, read authentic reviews, and connect with fellow book lovers in our digital library. +

+ +
+
+
+ + +
+
+ +
+ Books Illustration +
+
-
-
-

Browse by Categories

-
- @for (genre of browsingGenres(); track $index) { -
+
+
+ +
+

Browse by Genre

+
+
+ +
+ @for (genre of browsingGenres(); track $index) { + - } + } +
+
@@ -30,12 +77,12 @@

Browse by Categories

Popular this week

-
+
@for (book of popularBooks(); track $index) { - + }
- + \ No newline at end of file diff --git a/book-bazaar/src/app/components/home/home.ts b/book-bazaar/src/app/components/home/home.ts index 27239ca..cb4a9d7 100644 --- a/book-bazaar/src/app/components/home/home.ts +++ b/book-bazaar/src/app/components/home/home.ts @@ -41,7 +41,7 @@ export class Home { ngOnInit() { this.bookService.getBooks({}, 0, 5) .subscribe(page => this.popularBooks.set(page.items)); - this.genreService.getGenres(0, 5) + this.genreService.getGenres(0, 6) .subscribe(page => this.browsingGenres.set(page.items)); } diff --git a/book-bazaar/src/app/components/search-books/search-books.html b/book-bazaar/src/app/components/search-books/search-books.html index ea55350..b864182 100644 --- a/book-bazaar/src/app/components/search-books/search-books.html +++ b/book-bazaar/src/app/components/search-books/search-books.html @@ -1,67 +1,90 @@ -
-