Hvad skal vi designe næste gang? Din stemme er med til at afgøre vores næste produkt! Løbende vil vi præsentere jer for farver, funktioner og forskellige produkter. Du kan under hvert billede afgive din stemme på de designs, du kan lide eller ikke lide 👍👎
Sweater Skjorte Dame - Sand
Synes godt om
Synes ikke om
👍 0
👎 0
Sweater Skjorte Herre - Valnød
Synes godt om
Synes ikke om
👍 0
👎 0
Sweater Skjorte Herre - Kastanje
Synes godt om
Synes ikke om
👍 0
👎 0
Sweater Skjorte Dame - Sand
👍 0
👎 0
Sweater Skjorte Herre - Valnød
👍 0
👎 0
Sweater Skjorte Herre - Kastanje
👍 0
👎 0
Sweater Skjorte Dame - Sand
👍 0
👎 0
Sweater Skjorte Herre - Valnød
👍 0
👎 0
Sweater Skjorte Herre - Kastanje
👍 0
👎 0
async function getCustomerAccountUrl() {
try {
const response = await fetch("https://vimpulze.dk/api/unstable/graphql.json", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: `query { consentManagement { customerAccountUrl } }`
}),
});
const result = await response.json();
const accountUrl = result?.data?.consentManagement?.customerAccountUrl;
if (accountUrl) {
console.log("✅ Customer Account URL:", accountUrl);
return accountUrl;
} else {
console.warn("❌ Customer Account URL not found.");
return null;
}
} catch (error) {
console.error("❌ Error fetching Customer Account URL:", error);
}
}
// 🟢 Fetch User Identity (Email → Name → Customer ID → Guest)
async function getUserId() {
const accountUrl = await getCustomerAccountUrl();
if (accountUrl) {
const customerID = accountUrl.match(/shopify.com\/(\d+)\/account/)[1];
try {
const response = await fetch("/account/customer/api/unstable/graphql", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: `query Profile {
customer {
id
firstName
lastName
emailAddress {
emailAddress
}
}
}`,
}),
});
const result = await response.json();
const customer = result.data.customer;
if (customer) {
if (customer.firstName || customer.lastName) {
return `${customer.firstName || ""} ${customer.lastName || ""}`.trim(); // ✅ Name First
} else if (customer.emailAddress?.emailAddress) {
return customer.emailAddress.emailAddress; // ✅ Email Second
} else {
return `customer_${customerID}`; // ✅ Shopify ID Fallback
}
}
} catch (error) {
console.error("❌ Error fetching Shopify customer details:", error);
}
}
return `guest_${Math.random().toString(36).substring(2, 10)}`; // ✅ Generate guest ID
}
// 🟢 Load Votes
async function loadVotes() {
document.querySelectorAll(".vote-item").forEach(async item => {
const productId = item.getAttribute("data-product-id");
try {
const response = await fetch(`http://localhost:3000/votes/${productId}`);
if (!response.ok) throw new Error("Failed to fetch votes");
const data = await response.json();
document.getElementById(`likes-${productId}`).textContent = data.thumbsUp || 0;
document.getElementById(`dislikes-${productId}`).textContent = data.thumbsDown || 0;
} catch (error) {
console.error("❌ Error loading votes:", error);
}
});
}
// 🟢 Voting Function
async function vote(productId, type) {
const userId = await getUserId();
let voters = {};
try {
const response = await fetch(`http://localhost:3000/votes/${productId}`);
if (response.ok) {
const data = await response.json();
voters = data.voters || {};
}
} catch (error) {
console.error("❌ Error fetching voters:", error);
return;
}
if (voters[userId] === type) {
alert("❌ You have already voted for this option!");
return;
}
const likeCount = document.getElementById(`likes-${productId}`);
const dislikeCount = document.getElementById(`dislikes-${productId}`);
let currentLikes = parseInt(likeCount.textContent) || 0;
let currentDislikes = parseInt(dislikeCount.textContent) || 0;
if (voters[userId]) {
if (voters[userId] === "like") currentLikes = Math.max(0, currentLikes - 1);
if (voters[userId] === "dislike") currentDislikes = Math.max(0, currentDislikes - 1);
}
if (type === "like") {
currentLikes++;
} else {
currentDislikes++;
}
try {
const response = await fetch("http://localhost:3000/vote", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
productId: productId,
type: type,
userId: userId,
}),
});
const result = await response.json();
if (!response.ok || result.error) throw new Error("Vote update failed");
voters[userId] = type;
likeCount.textContent = currentLikes;
dislikeCount.textContent = currentDislikes;
console.log(`✅ Vote updated for ${productId}: ${type}`);
} catch (error) {
console.error("❌ Error updating vote:", error);
}
}
// 🟢 Initialize Votes on Page Load
document.addEventListener("DOMContentLoaded", () => {
loadVotes();
document.querySelectorAll(".vote-item .vote-btn").forEach(button => {
button.addEventListener("click", function () {
const productId = this.closest(".vote-item").getAttribute("data-product-id");
const voteType = this.getAttribute("data-vote");
vote(productId, voteType);
});
});
});