Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion book-bazaar/src/app/components/book-card/book-card.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<a [routerLink]="['/book-details', book().id]" class="block h-full no-underline text-inherit group">
<div class="h-full">
<mat-card appearance="outlined"
class="h-full flex flex-col w-full border-gray-200 bg-white transition-all duration-300 group-hover:shadow-lg group-hover:border-primary/20 group-hover:-translate-y-1">
class="h-full flex flex-col w-full border-gray-200 !bg-white transition-all duration-300 group-hover:shadow-lg group-hover:border-primary/20 group-hover:-translate-y-1">

<div
class="p-6 flex justify-center items-center bg-gray-50 rounded-t-lg border-b border-gray-100 aspect-[3/4] relative overflow-hidden">
Expand Down
15 changes: 15 additions & 0 deletions book-bazaar/src/app/components/book-details/book-details.css
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,19 @@
height: auto;
width: auto;
font-size: 24px;
}

::ng-deep .custom-user-menu {
border-radius: 16px !important;
overflow: hidden !important;
min-width: 220px !important;
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.01) !important;
margin-top: 8px !important;

/* ДОДАНО: Примусовий білий фон */
background-color: white !important;
}

::ng-deep .mat-mdc-paginator {
background-color: white !important;
}
4 changes: 2 additions & 2 deletions book-bazaar/src/app/components/book-details/book-details.html
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ <h3 class="text-xl font-bold text-gray-900 flex items-center gap-2">
<mat-icon iconPositionEnd class="text-gray-500 ml-1">expand_more</mat-icon>
</button>

<mat-menu #sortMenu="matMenu" xPosition="before" class="mt-2">
<mat-menu #sortMenu="matMenu" xPosition="before" class="mt-2 custom-user-menu">
<button mat-menu-item (click)="onSortChange('createdAt,desc')"
[class.bg-blue-50]="currentSort() === 'createdAt,desc'">
<span [class.font-bold]="currentSort() === 'createdAt,desc'">Newest first</span>
Expand Down Expand Up @@ -288,7 +288,7 @@ <h3 class="text-xl font-bold text-gray-900 flex items-center gap-2">
}
</div>

<div class="mt-8 border-t border-gray-100 pt-4">
<div class="mt-12 bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
<mat-paginator
[length]="reviewsTotal()"
[pageSize]="pageSize()"
Expand Down
44 changes: 44 additions & 0 deletions book-bazaar/src/app/components/dialog/confirm-dialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Component, inject } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';

@Component({
selector: 'app-confirm-dialog',
standalone: true,
imports: [MatDialogModule, MatButtonModule],
template: `
<div class="p-6 bg-white">
<h2 class="text-xl font-serif font-bold text-gray-900 mb-2 leading-tight">
Delete Review?
</h2>

<p class="text-gray-500 mb-8 text-base leading-relaxed">
This action cannot be undone. Are you sure you want to remove this review permanently?
</p>

<div class="flex justify-end gap-3">
<button mat-button
(click)="dialogRef.close(false)"
class="!font-medium !text-gray-600 hover:!bg-gray-50 !rounded-full">
Cancel
</button>

<button mat-flat-button
color="warn"
(click)="dialogRef.close(true)"
class="!rounded-full !px-6 shadow-md shadow-red-100">
Delete
</button>
</div>
</div>
`,
styles: [`
:host {
display: block;
background: white;
}
`]
})
export class ConfirmDialog {
readonly dialogRef = inject(MatDialogRef<ConfirmDialog>);
}
89 changes: 68 additions & 21 deletions book-bazaar/src/app/components/footer/footer.html
Original file line number Diff line number Diff line change
@@ -1,30 +1,77 @@
<section class="flex h-fit p-5 justify-between items-center bg-dark h-2/5 font-sans text-secondary-trans font-medium text-lg">
<div class="w-full">
<div class="flex items-center">
<div class="h-40">
<a [routerLink]="['/']">
<img class="w-full h-full object-cover object-center" src="BookBazaar-logo-transparent.png" alt="BookBazaar">
<footer class="bg-white border-t border-gray-100 pt-16 pb-8 font-sans relative z-10">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">

<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-12 gap-8 lg:gap-12 mb-12">

<div class="lg:col-span-4 flex flex-col gap-6">
<a [routerLink]="['/']" class="flex items-center gap-2 group no-underline w-fit">
<div class="w-10 h-10 bg-gradient-to-br from-primary to-tertiary rounded-xl flex items-center justify-center text-white shadow-sm">
<span class="material-icons scale-110">local_library</span>
</div>
<span class="font-serif text-2xl font-bold text-gray-900 tracking-tight">
Book<span class="text-primary">Bazaar</span>
</span>
</a>
</div>
<div class="text-wrap">
<p class="hover:text-secondary">
Your digital gateway to endless literary adventures. Discover, read, and review thousands of books.

<p class="text-gray-500 leading-relaxed text-sm max-w-sm">
Your digital gateway to endless literary adventures. Discover, read, and review thousands of books in our curated digital library.
</p>
<div class="flex">
<a class="pl-0 social-link">
<img src="icons8-instagram-50.png" alt="Inst"/>

<div class="flex items-center gap-4 mt-2">
<a href="#" class="social-btn group">
<img src="icons8-instagram-50.png" alt="Instagram" class="w-5 h-5 opacity-60 group-hover:opacity-100 transition-opacity">
</a>
<a class="social-link">
<img src="icons8-x-50.png" alt="X"/>
<a href="#" class="social-btn group">
<img src="icons8-x-50.png" alt="X (Twitter)" class="w-5 h-5 opacity-60 group-hover:opacity-100 transition-opacity">
</a>
</div>
</div>

<div class="lg:col-span-8 grid grid-cols-2 sm:grid-cols-3 gap-8">

<div>
<h3 class="font-serif font-bold text-gray-900 mb-4">Discover</h3>
<ul class="space-y-3">
<li><a routerLink="/search" class="footer-link">Bestsellers</a></li>
<li><a routerLink="/search" class="footer-link">New Releases</a></li>
<li><a routerLink="/search" class="footer-link">Authors</a></li>
<li><a routerLink="/search" class="footer-link">Genres</a></li>
</ul>
</div>

<div>
<h3 class="font-serif font-bold text-gray-900 mb-4">Community</h3>
<ul class="space-y-3">
<li><a routerLink="/my-reviews" class="footer-link">My Reviews</a></li>
<li><a href="#" class="footer-link">Discussion Forums</a></li>
<li><a href="#" class="footer-link">Book Clubs</a></li>
<li><a href="#" class="footer-link">Blog</a></li>
</ul>
</div>

<div>
<h3 class="font-serif font-bold text-gray-900 mb-4">Support</h3>
<ul class="space-y-3">
<li><a href="#" class="footer-link">Help Center</a></li>
<li><a href="#" class="footer-link">Contact Us</a></li>
<li><a href="#" class="footer-link">Privacy Policy</a></li>
<li><a href="#" class="footer-link">Terms of Service</a></li>
</ul>
</div>

</div>
</div>

<div class="border-t border-gray-100 pt-8 flex flex-col md:flex-row justify-between items-center gap-4">
<p class="text-gray-400 text-sm font-light">
© 2025 BookBazaar. All rights reserved.
</p>
<div class="flex gap-6">
<a href="#" class="text-xs text-gray-400 hover:text-primary transition-colors">Privacy</a>
<a href="#" class="text-xs text-gray-400 hover:text-primary transition-colors">Terms</a>
<a href="#" class="text-xs text-gray-400 hover:text-primary transition-colors">Cookies</a>
</div>
</div>

<div class="flex flex-col"></div>
<div class="flex flex-col"></div>
<div class="flex flex-col"></div>
<hr>
<p class="text-center p-10 text-sm font-light pb-0">© 2025 BookBazaar. All rights reserved.</p>
</div>
</section>
</footer>
10 changes: 10 additions & 0 deletions book-bazaar/src/app/components/header/header.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
::ng-deep .custom-user-menu {
border-radius: 16px !important;
overflow: hidden !important;
min-width: 220px !important;
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.01) !important;
margin-top: 8px !important;

/* ДОДАНО: Примусовий білий фон */
background-color: white !important;
}
128 changes: 83 additions & 45 deletions book-bazaar/src/app/components/header/header.html
Original file line number Diff line number Diff line change
@@ -1,52 +1,90 @@
<section class="p-4 bg-primary text-white">
<div class="flex items-center justify-between pl-20 pr-20">
<div class="flex items-center max-w-2/5">
<a [routerLink]="['/']" class="w-3xs h-15">
<img class="w-full h-full object-cover object-center" src="collage.png" alt="Logo">
</a>
<a [routerLink]="['/search']" class="h-15 pt-3 ml-4">
<div class="text-secondary text-xl hover:text-secondary-trans font-medium">Search</div>
</a>
</div>
<header
class="sticky top-0 z-40 w-full bg-white/80 backdrop-blur-md border-b border-gray-100 transition-all duration-300">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-20">
<div class="flex items-center gap-8">
<a [routerLink]="['/']" class="flex items-center gap-2 group no-underline">
<div
class="w-10 h-10 bg-gradient-to-br from-primary to-tertiary rounded-xl flex items-center justify-center text-white shadow-sm group-hover:shadow-md transition-all">
<mat-icon class="scale-110">local_library</mat-icon>
</div>
<span
class="font-serif text-2xl font-bold text-gray-900 tracking-tight group-hover:text-primary transition-colors">
Book<span class="text-primary">Bazaar</span>
</span>
</a>

<div>
@if (userService.isLoggedIn()) {
<button [matMenuTriggerFor]="userMenu" class="flex items-center gap-2 cursor-pointer focus:outline-none">
<span class="text-lg font-medium mr-2">
{{ userService.userProfile()?.firstName }}
</span>

<div
class="w-10 h-10 rounded-full overflow-hidden bg-gray-200 border-2 border-white flex justify-center items-center">
@if (userService.avatarUrl()) {
<img [src]="userService.avatarUrl()" alt="Avatar" class="w-full h-full object-cover"
referrerpolicy="no-referrer">
} @else {
<mat-icon class="text-gray-500 scale-125">person</mat-icon>
}
</div>
</button>
<nav class="hidden md:flex items-center gap-6">
<a [routerLink]="['/search']"
class="text-sm font-medium text-gray-600 hover:text-primary transition-colors flex items-center gap-1">
<mat-icon class="scale-90">search</mat-icon>
Browse Books
</a>
</nav>
</div>

<mat-menu #userMenu="matMenu">
<button mat-menu-item disabled>
<span>{{ userService.userProfile()?.email }}</span>
</button>
<button mat-menu-item routerLink="/my-reviews">
<mat-icon>rate_review</mat-icon>
<span>My Reviews</span>
</button>
<button mat-menu-item (click)="userService.logout()">
<mat-icon>logout</mat-icon>
<span>Log out</span>
<div class="flex items-center gap-4">

@if (userService.isLoggedIn()) {
<button [matMenuTriggerFor]="userMenu"
class="flex items-center gap-3 pl-1 pr-2 py-1 rounded-full hover:bg-gray-50 transition-all border border-transparent hover:border-gray-200 cursor-pointer focus:outline-none">

<div class="flex flex-col items-end hidden sm:block">
<span class="text-sm font-bold text-gray-800 leading-none">
{{ userService.userProfile()?.firstName }}
</span>
<span class="text-[10px] text-gray-500 font-medium">My Account</span>
</div>

<div class="w-10 h-10 rounded-full overflow-hidden bg-gray-100 ring-2 ring-white shadow-sm">
@if (userService.avatarUrl()) {
<img [src]="userService.avatarUrl()" alt="Avatar" class="w-full h-full object-cover" referrerpolicy="no-referrer">
} @else {
<div class="w-full h-full flex items-center justify-center text-gray-400">
<mat-icon>person</mat-icon>
</div>
}
</div>

<mat-icon class="text-gray-400 scale-75">expand_more</mat-icon>
</button>
</mat-menu>

} @else {
<div class="flex gap-2">
<button matButton (click)="userService.login()">Log In</button>
<button mat-raised-button color="accent" (click)="userService.register()">Sign Up</button>
<mat-menu #userMenu="matMenu" xPosition="before" class="custom-user-menu">
<div class="px-4 py-3 border-b border-gray-100 mb-2">
<p class="text-sm font-bold text-gray-900">Signed in as</p>
<p class="text-xs text-gray-500 truncate max-w-[150px]">{{ userService.userProfile()?.email }}</p>
</div>

<button mat-menu-item routerLink="/my-reviews">
<mat-icon class="text-primary">rate_review</mat-icon>
<span>My Reviews</span>
</button>
<button mat-menu-item>
<mat-icon class="text-gray-500">settings</mat-icon>
<span>Settings</span>
</button>

<div class="border-t border-gray-100 mt-2 pt-2">
<button mat-menu-item (click)="userService.logout()">
<mat-icon class="text-red-500">logout</mat-icon>
<span class="text-red-500">Log out</span>
</button>
</div>
</mat-menu>

} @else {
<div class="flex items-center gap-3">
<button mat-button (click)="userService.login()"
class="!font-medium !text-gray-600 hover:!text-primary hover:!bg-primary/5 !rounded-full">
Log In
</button>
<button mat-flat-button color="primary" (click)="userService.register()"
class="!rounded-full !px-6 !font-bold shadow-md shadow-primary/20">
Sign Up
</button>
</div>
}
</div>
}
</div>
</div>
</section>
</header>
Loading
Loading