Show recently viewed product from local storage

use of getLocalStorage action to get recently viewed 10 products

<div class="recently-viewed-section">
  <div class="recently-viewed-scroll-wrapper">
    <div id="recentlyViewedContainer" class="recently-viewed-scroll"></div>
  </div>
</div>
/* Recently Viewed Section */
.recently-viewed-section {
  padding: 12px 8px;
}
/* Heading (optional) */
.recently-viewed-heading {
  font-family: 'Cormorant Garamond', serif;
  font-size: 24px;
  font-weight: 300;
  text-align: center;
  color: #202020;
  margin: 0;
}
.recently-viewed-heading i {
  font-style: italic;
}
/* Scrollable container */
.recently-viewed-scroll-wrapper {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  scroll-behavior: smooth;
  overscroll-behavior-x: contain;
}
.recently-viewed-scroll-wrapper::-webkit-scrollbar {
  display: none;
}
.recently-viewed-scroll {
  display: flex;
  gap: 8px;
}
/* Card */
.recently-viewed-card {
  flex: 0 0 54%;
  overflow: hidden;
}
.image-wrapper {
  position: relative;
  width: 100%;
  aspect-ratio: 3.8/5;
  overflow: hidden;
}
.recently-viewed-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  cursor: pointer;
  transition: transform .2s ease;
}
.recently-viewed-img:active {
  transform: scale(.97);
}
/* Content */
.recently-viewed-card-content {
  text-align: left;
  padding: 8px;
}
/* Title */
.recently-viewed-card-content h3.title {
  margin: 1px 0 2px;
  font-family: 'Montserrat', sans-serif;
  font-size: 14px;
  font-weight: 400;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  text-transform: capitalize;
}
/* Price */
.recently-viewed-card-content h4.price {
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-size: 12px;
  margin-top: 4px;
}
/* Add to Cart Button */
.add-to-cart-btn {
  width: 100%;
  height: 33px;
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0 0 1px;
  border: none;
  border-radius: 0;
  cursor: pointer;
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-size: 10px;
  color: #000;
  background: #e2e2e2;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.add-to-cart-btn:active {
  opacity: .9;
}
.gif-loader {
  display: none;
  width: 12px;
  height: 12px;
  margin-left: 6px;
}
const RV_KEY = "recentlyViewedProducts";
async function rvGetStoredProducts() {
  const raw = await VajroSDK.actions.getLocalStorage(RV_KEY);
  try { return raw ? JSON.parse(raw) : []; } catch { return []; }
}
async function rvOpenProduct(handle) {
  try { await VajroSDK.actions.openProduct({ productHandle: handle }); }
  catch (err) { console.error("openProduct failed:", err); }
}
function rvIsRenderable(p) {
  // minimal fields required to render a proper card
  const hasTitle = !!p?.title;
  const hasHandle = !!p?.handle;
  const firstImage = p?.images?.[0];
  const imageUrl = typeof firstImage === "string" ? firstImage : firstImage?.url || firstImage?.src;
  const firstVariant = p?.variants?.[0];
  const hasPrice = Number.isFinite(Number(firstVariant?.price || 0));
  return hasTitle && hasHandle && !!imageUrl && hasPrice;
}
function rvGetFirstImageUrl(p) {
  const img = p?.images?.[0];
  if (!img) return "";
  return typeof img === "string" ? img : (img.url || img.src || "");
}
async function rvRender() {
  const section = document.querySelector(".recently-viewed-section");
  const container = document.getElementById("recentlyViewedContainer");
  if (!section || !container) return;
  const products = await rvGetStoredProducts();
  // Filter to only renderable products
  const safeProducts = products.filter(rvIsRenderable);
  if (!safeProducts.length) {
    section.style.display = "none";
    return;
  }
  container.innerHTML = "";
  safeProducts.forEach(product => {
    const firstVariant = product?.variants?.[0] || {};
    const isSingleVariant = (product?.variants?.length || 0) === 1;
    const price = Number(firstVariant?.price || 0);
    const compareAt = Number(firstVariant?.compareAtPrice || 0);
    const hasDiscount = compareAt > price;
    const image = rvGetFirstImageUrl(product);
    const card = document.createElement("div");
    card.className = "recently-viewed-card";
    card.innerHTML = `
      <div class="image-wrapper">
        <img src="${image}" alt="${product?.title || ""}" class="recently-viewed-img" />
      </div>
      <outlined-button class="add-to-cart-btn">
        <span class="btn-text">${isSingleVariant ? "ADD TO CART" : "Choose Options"}</span>
        <img src="https://res.cloudinary.com/dixyq8hvr/image/upload/v1747722131/cupertino_activity_indicator_zze4pb.gif" class="gif-loader" />
      </outlined-button>
      <div class="recently-viewed-card-content">
        <h3 class="title">${product?.title || ""}</h3>
        <h4 class="price">
          ₹${price.toLocaleString("en-IN")}
          ${hasDiscount ? `<span style="text-decoration:line-through;color:#989898;margin-left:4px;">₹${compareAt.toLocaleString("en-IN")}</span>` : ""}
        </h4>
      </div>
    `;
    // Open PDP
    card.querySelector(".recently-viewed-img")
      ?.addEventListener("click", () => rvOpenProduct(product?.handle));
    // AddToCart or Choose Options
    const button = card.querySelector(".add-to-cart-btn");
    const btnText = button.querySelector(".btn-text");
    const loader = button.querySelector(".gif-loader");
    if (isSingleVariant && firstVariant?.id) {
      button.addEventListener("click", async (e) => {
        e.stopPropagation();
        button.disabled = true;
        btnText.style.display = "none";
        loader.style.display = "inline-block";
        try {
          await VajroSDK.actions.addToCart([{ variantId: String(firstVariant.id), quantity: 1 }]);
          await VajroSDK.actions.showToast?.({ title: "Added to Cart", message: "Product added successfully" });
        } catch (err) {
          console.error("⚠️ Add to Cart failed:", err);
        } finally {
          button.disabled = false;
          btnText.style.display = "inline";
          loader.style.display = "none";
        }
      });
    } else {
      button.addEventListener("click", (e) => {
        e.stopPropagation();
        rvOpenProduct(product?.handle);
      });
    }
    container.appendChild(card);
  });
  // If for some reason nothing appended, hide section
  if (!container.children.length) {
    section.style.display = "none";
    return;
  }
  if (VajroSDK?.actions?.resizeBlock) {
    await VajroSDK.actions.resizeBlock();
  }
}
document.addEventListener("DOMContentLoaded", rvRender);