Skip to content

Instantly share code, notes, and snippets.

@thibautrey
Last active January 15, 2025 13:01
Show Gist options
  • Save thibautrey/d4249687dc7aa3e88de73d2992d4d8f9 to your computer and use it in GitHub Desktop.
Save thibautrey/d4249687dc7aa3e88de73d2992d4d8f9 to your computer and use it in GitHub Desktop.
Sku Shopify
// ==UserScript==
// @name Enhanced SKU Display with Competitor Links
// @namespace http://tampermonkey.net/
// @version 2024.4
// @description Display SKU as a clickable copy button with competitor links in-line, refreshing existing tabs
// @match https://admin.shopify.com/store/*/products/*
// @grant none
// @require https://gist.githubusercontent.com/yourusername/yourgistid/raw/login.js
// ==/UserScript==
(function () {
"use strict";
const openTabs = {};
async function execute() {
try {
// Get the SKU value from the element with ID "InventoryCardSku"
let skuElement = document.getElementById("InventoryCardSku");
if (!skuElement) throw new Error("SKU element not found");
let skuValue = skuElement.value.split("-")[1];
if (!skuValue) throw new Error("SKU value not found");
if (skuValue.length <= 2) throw new Error("SKU empty");
// Find the <h2> element with the specified classes and text "Statut"
let form = document.querySelectorAll("form");
let statutHeader = form[0];
if (!statutHeader) throw new Error('"Statut" header not found');
// Check if SKU container already exists to avoid duplicates
if (document.getElementById("custom-sku-container")) return;
// Create a container div for SKU and competitor links, inline style
let containerDiv = document.createElement("div");
containerDiv.id = "custom-sku-container";
containerDiv.style.display = "flex";
containerDiv.style.alignItems = "center";
containerDiv.style.marginBottom = "10px";
containerDiv.style.fontFamily = "Arial, sans-serif";
containerDiv.style.position = "relative";
// SKU label (acts as copy button)
let skuLabel = document.createElement("button");
skuLabel.textContent = `SKU: ${skuValue}`;
skuLabel.style.fontSize = "16px";
skuLabel.style.fontWeight = "500";
skuLabel.style.background = "none";
skuLabel.style.border = "none";
skuLabel.style.cursor = "pointer";
skuLabel.style.marginRight = "15px";
skuLabel.style.padding = "5px 10px";
skuLabel.style.color = "#0073e6";
skuLabel.addEventListener("click", () => {
navigator.clipboard
.writeText(skuValue)
.then(() => {
alert("SKU copied to clipboard!");
})
.catch((err) => {
console.error("Failed to copy text: ", err);
});
});
containerDiv.appendChild(skuLabel);
// Fetch competitor URLs
const productId = document.location.href.split("/").pop();
const response = await fetch(
`https://price-tracker-api.astronomy-store.com/api/competitor-url-with-shopify-product-id/${productId}`,
{
headers: {
"x-api-key":
"Um5ztH9GPWrxaHJVrgixvtXdLycQK2LVZ4DroM3hYyT6JSVW9XZVb36q2Y8cJDGaP5DeUd",
Authorization: `Bearer ${localStorage.getItem("jwt")}`,
},
}
);
const competitors = await response.json();
// Add competitor link buttons, inline style
competitors.results.forEach((competitor) => {
const button = document.createElement("button");
button.textContent = `${competitor.competitor.name}`;
button.style.marginRight = "10px";
button.style.padding = "5px 10px";
button.style.border = "1px solid #ddd";
button.style.borderRadius = "4px";
button.style.cursor = "pointer";
button.addEventListener("click", () => {
const url = competitor.productUrl;
if (openTabs[competitor.name] && !openTabs[competitor.name].closed) {
openTabs[competitor.name].location.href = url; // Refresh the existing tab
openTabs[competitor.name].focus();
} else {
openTabs[competitor.name] = window.open(url, `_blank`); // Open a new tab if not already open
}
});
containerDiv.appendChild(button);
});
// Ajouter l'affichage des images des produits concurrents
displayCompetitorImages(competitors.results, skuValue);
// Insert the container before the "Statut" header
statutHeader.insertAdjacentElement("beforebegin", containerDiv);
} catch (e) {
console.log(e);
setTimeout(execute, 1000); // Retry if elements not yet found
}
}
function displayCompetitorImages(competitors, sku) {
competitors.forEach((competitor) => {
fetch(
`https://price-tracker-api.astronomy-store.com/api/competitor-products/${competitor.id}/images`,
{
headers: { Authorization: `Bearer ${localStorage.getItem("jwt")}` },
}
)
.then((response) => response.json())
.then((data) => {
const images = data.images.filter((img) => img.sku === sku);
if (images.length > 0) {
showImagesPopup(competitor.name, images);
}
})
.catch((err) =>
console.error("Erreur lors de la récupération des images:", err)
);
});
}
function showImagesPopup(competitorName, images) {
const popup = document.createElement("div");
popup.className = "images-popup astro-popup";
popup.style.cssText = `
position: fixed;
top: 100px;
right: 20px;
background-color: #fff;
border: 1px solid #ccc;
padding: 15px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
z-index: 1001;
color: black;
max-width: 300px;
overflow-y: auto;
`;
popup.innerHTML = `
<h3>Images de ${competitorName}</h3>
<div style="display: flex; flex-wrap: wrap; gap: 10px;">
${images
.map((img) => `<img src="${img.url}" style="max-width: 80px;">`)
.join("")}
</div>
<button onclick="this.parentElement.remove()" style="margin-top: 10px; padding: 5px 10px;">Fermer</button>
`;
document.body.appendChild(popup);
}
execute();
window.navigation.addEventListener("navigatesuccess", (e) => {
execute();
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment