PageSourceSearch

https://aadilmallick.com/js/product.js

js aadilmallick.com collected 2026-10-08 02:09:23 UTC 3,048 bytes, 98 lines download raw bytes

1import { DOM, html } from "./DOM.js";
2import { initTilt } from "./tilt.js";
3
4/**
5 * Fetches notebook products from the JSON file.
6 * @returns {Promise<Array>} Array of product objects.
7 */
8async function fetchNotebooks() {
9  try {
10  const jsonUrl = new URL('../json/notebook-products.json', import.meta.url).href;
11  const response = await fetch(jsonUrl);
12    if (!response.ok) {
13      throw new Error('Failed to fetch products');
14    }
15    const notebooks = await response.json();
16    // Store in localStorage
17    localStorage.setItem('notebookProducts', JSON.stringify(notebooks));
18    return notebooks;
19  } catch (error) {
20    console.error('Fetch failed:', error);
21    // Try to get from localStorage
22    const cached = localStorage.getItem('notebookProducts');
23    if (cached) {
24      return JSON.parse(cached);
25    }
26    throw error;
27  }
28}
29
30/**
31 * Creates a product card element.
32 * @param {Object} product - The product object.
33 * @param {string} product.title - Product title.
34 * @param {string} product.price - Product price.
35 * @param {string} product.link - Checkout link.
36 * @param {string} product.description - Product description.
37 * @param {string} product.id - Product ID.
38 * @returns {HTMLElement} The card element.
39 */
40function createProductCard(product) {
41  const imageUrl = new URL(`../images/products/${product.id}.jpg`, import.meta.url).href;
42    const cardHtml = html`
43        <div class="product-card">
44            <img 
45                src="${imageUrl}" 
46                alt="${product.title}"
47                class="product-image"
48            >
49            <div class="product-info">
50                <h3 class="product-title">${product.title}</h3>
51                <p class="product-price">${product.price}</p>
52                <p class="product-description">${product.description || 'No description available.'}</p>
53                <a href="${product.link}" target="_blank" class="checkout-button">Checkout</a>
54            </div>
55        </div>
56    `;
57    
58    return DOM.createDomElement(cardHtml);
59}
60
61/**
62 * Renders the products to the page.
63 * @param {Array} products - Array of product objects.
64 */
65function renderProducts(products) {
66  const container = document.getElementById('products-container');
67  container.innerHTML = ''; // Clear existing
68  products.forEach(product => {
69    const card = createProductCard(product);
70    container.appendChild(card);
71  });
72}
73
74/**
75 * Displays an error message.
76 * @param {string} message - The error message.
77 */
78function showError(message) {
79  const container = document.getElementById('products-container');
80  container.innerHTML = `<p class="error-message">${message}</p>`;
81}
82
83/**
84 * Initializes the product loading.
85 */
86async function initProducts() {
87  try {
88    const products = await fetchNotebooks();
89    renderProducts(products);
90  // init tilt on freshly rendered images
91  initTilt();
92  } catch (error) {
93    showError('Failed to load products. Please try again later.');
94  }
95}
96
97// Load products on page load
98document.addEventListener('DOMContentLoaded', initProducts);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.