diff --git a/js/app.js b/js/app.js
index 69c327f..e57a1b1 100644
--- a/js/app.js
+++ b/js/app.js
@@ -19,6 +19,7 @@ import "./components/add-to-cart-button.js";
import "./components/cta-button.js";
import "./components/category-card.js";
import "./components/newsletter-signup.js";
+import "./components/book-details.js";
// Import icon components
import "./icons/menu-icon.js";
diff --git a/js/components/book-details.js b/js/components/book-details.js
new file mode 100644
index 0000000..cac2158
--- /dev/null
+++ b/js/components/book-details.js
@@ -0,0 +1,458 @@
+/**
+ * Book Details Component
+ * Displays book information with cover, metadata, and purchase buttons
+ */
+import { shoppingBagIcon } from "../icons/shopping-bag.js";
+
+class BookDetails extends HTMLElement {
+ static get observedAttributes() {
+ return [
+ "title",
+ "author",
+ "author-href",
+ "price",
+ "image",
+ "isbn",
+ "format",
+ "delivery",
+ "categories",
+ "ebook-available",
+ ];
+ }
+
+ constructor() {
+ super();
+ this.attachShadow({ mode: "open" });
+ }
+
+ connectedCallback() {
+ this.render();
+ this.setupEventListeners();
+ }
+
+ attributeChangedCallback() {
+ if (this.shadowRoot) {
+ this.render();
+ this.setupEventListeners();
+ }
+ }
+
+ setupEventListeners() {
+ const addToCartBtn = this.shadowRoot?.querySelector(".btn-cart");
+ const ebookBtn = this.shadowRoot?.querySelector(".btn-ebook");
+ const favoriteBtn = this.shadowRoot?.querySelector(".favorite-btn");
+
+ if (addToCartBtn) {
+ addToCartBtn.addEventListener("click", () => {
+ this.dispatchEvent(
+ new CustomEvent("add-to-cart", {
+ bubbles: true,
+ composed: true,
+ detail: {
+ title: this.bookTitle,
+ price: this.price,
+ type: "physical",
+ },
+ })
+ );
+ });
+ }
+
+ if (ebookBtn) {
+ ebookBtn.addEventListener("click", () => {
+ this.dispatchEvent(
+ new CustomEvent("buy-ebook", {
+ bubbles: true,
+ composed: true,
+ detail: {
+ title: this.bookTitle,
+ type: "ebook",
+ },
+ })
+ );
+ });
+ }
+
+ if (favoriteBtn) {
+ favoriteBtn.addEventListener("click", () => {
+ favoriteBtn.classList.toggle("active");
+ this.dispatchEvent(
+ new CustomEvent("toggle-favorite", {
+ bubbles: true,
+ composed: true,
+ detail: {
+ title: this.bookTitle,
+ },
+ })
+ );
+ });
+ }
+ }
+
+ get bookTitle() {
+ return this.getAttribute("title") || "Book Title";
+ }
+
+ get author() {
+ return this.getAttribute("author") || "Author Name";
+ }
+
+ get authorHref() {
+ return this.getAttribute("author-href") || "#";
+ }
+
+ get price() {
+ return this.getAttribute("price") || "€ 0,00";
+ }
+
+ get image() {
+ return this.getAttribute("image") || "";
+ }
+
+ get isbn() {
+ return this.getAttribute("isbn") || "";
+ }
+
+ get format() {
+ return this.getAttribute("format") || "Paperback";
+ }
+
+ get delivery() {
+ return this.getAttribute("delivery") || "Direct leverbaar";
+ }
+
+ get categories() {
+ return this.getAttribute("categories") || "";
+ }
+
+ get ebookAvailable() {
+ return this.hasAttribute("ebook-available");
+ }
+
+ renderCategories() {
+ if (!this.categories) return "";
+
+ // Categories are comma-separated, with optional href in format: "Name|href,Name2|href2"
+ const cats = this.categories.split(",").map((cat) => {
+ const [name, href] = cat.trim().split("|");
+ if (href) {
+ return `
${name}`;
+ }
+ return `
${name}`;
+ });
+
+ return cats.join('
/ ');
+ }
+
+ render() {
+ const imageHtml = this.image
+ ? `

`
+ : `
+
+
`;
+
+ this.shadowRoot.innerHTML = `
+
+
+
+
+
+
+
+
+
+ ${imageHtml}
+
+
+ ${
+ this.categories
+ ? `
+
+ Categorieën
+ ${this.renderCategories()}
+
+ `
+ : ""
+ }
+
+ ${
+ this.isbn
+ ? `
+
+ ISBN
+ ${this.isbn}
+
+ `
+ : ""
+ }
+
+ Uitvoering
+ ${this.format}
+
+
+
+
+ Uitvoering
+ ${this.format}
+
+
+ Levertijd
+ ${this.delivery}
+
+
+
+
+
+
+
+
+ `;
+ }
+}
+
+customElements.define("book-details", BookDetails);