const CONFIG = { API_BASE_URL: "http://localhost:4000/api/v1", // API_BASE_URL: "https://bids.apactech.io/api/v1", }; let PREV_DATA = null; function removeFalsyValues(obj, excludeKeys = []) { return Object.entries(obj).reduce((acc, [key, value]) => { if (value || excludeKeys.includes(key)) { acc[key] = value; } return acc; }, {}); } function extractDomain(url) { try { const parsedUrl = new URL(url); return parsedUrl.origin; } catch (error) { return null; } } function extractModelId(url) { switch (extractDomain(url)) { case "https://www.grays.com": { const match = url.match(/\/lot\/([\d-]+)\//); return match ? match[1] : null; } case "https://www.langtons.com.au": { const match = url.match(/auc-var-\d+/); return match[0]; } case "https://www.lawsons.com.au": { const match = url.split("_"); return match ? match[1] : null; } case "https://www.pickles.com.au": { const model = url.split("/").pop(); return model ? model : null; } } } const showPage = async (pageLink = "pages/popup/popup.html") => { const res = await fetch(chrome.runtime.getURL(pageLink)); const html = await res.text(); const wrapper = document.createElement("div"); wrapper.innerHTML = html; document.body.appendChild(wrapper); }; const getKey = () => { return new Promise((resolve, reject) => { chrome.storage.local.get("key", (result) => { if (chrome.runtime.lastError) { reject(chrome.runtime.lastError); } else { resolve(result.key || null); } }); }); }; async function handleCreate(event, formElements) { event.preventDefault(); const key = await getKey(); if (!key) { showKey(); return; } const maxPrice = parseFloat(formElements.maxPrice.value); const plusPrice = parseFloat(formElements.plusPrice.value); const quantity = parseInt(formElements.quantity.value, 10); const payload = { url: formElements.url.value.trim(), max_price: isNaN(maxPrice) ? null : maxPrice, plus_price: isNaN(plusPrice) ? null : plusPrice, quantity: isNaN(quantity) ? null : quantity, }; // Validate required fields if (!payload.url || payload.max_price === null) { alert("Please fill out the URL and Max Price fields correctly."); return; } try { const response = await fetch(`${CONFIG.API_BASE_URL}/bids`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: key, }, body: JSON.stringify(removeFalsyValues(payload)), }); const result = await response.json(); alert(result.message); // showInfo await showInfo(extractModelId(payload.url), formElements); // handleChangeTitleButton handleChangeTitleButton(true, formElements); } catch (error) { alert("Error: " + error.message); console.error("API Error:", error); } } async function handleUpdate(event, formElements, id) { event.preventDefault(); const key = await getKey(); if (!key) { showKey(); return; } const maxPrice = parseFloat(formElements.maxPrice.value); const plusPrice = parseFloat(formElements.plusPrice.value); const quantity = parseInt(formElements.quantity.value, 10); const payload = { max_price: isNaN(maxPrice) ? null : maxPrice, plus_price: isNaN(plusPrice) ? null : plusPrice, quantity: isNaN(quantity) ? null : quantity, }; // Validate required fields if (payload.max_price === null) { alert("Please fill out the URL and Max Price fields correctly."); return; } try { const response = await fetch(`${CONFIG.API_BASE_URL}/bids/info/${id}`, { method: "PUT", headers: { "Content-Type": "application/json", Authorization: key, }, body: JSON.stringify(removeFalsyValues(payload)), }); const result = await response.json(); alert(result.message); } catch (error) { alert("Error: " + error.message); console.error("API Error:", error); } } const showBid = () => { const formKey = document.getElementById("form-key"); const formBid = document.getElementById("form-bid"); formKey.style.display = "none"; formBid.style.display = "block"; }; const showKey = async () => { const key = await getKey(); const formKey = document.getElementById("form-key"); const formBid = document.getElementById("form-bid"); const keyEl = document.querySelector("#form-key #key"); formBid.style.display = "none"; formKey.style.display = "block"; if (key && keyEl) { keyEl.value = key; } }; const handleToogle = async () => { const btn = document.getElementById("toggle-bid-extension"); const panel = document.getElementById("bid-extension"); // Kiểm tra xem nút và panel có tồn tại hay không if (btn && panel) { btn.addEventListener("click", async () => { panel.style.display = panel.style.display === "none" ? "block" : "none"; await handleShowForm(); }); } else { console.error("Không tìm thấy nút hoặc panel!"); } }; const handleShowForm = async () => { const toggleBtn = document.getElementById("toggle-bid-extension"); const formBid = document.getElementById("form-bid"); const formKey = document.getElementById("form-key"); const keyBtn = document.getElementById("key-btn"); const isVisible = (el) => el && el.style.display !== "none"; // Toggle hiển thị form hiện tại (bid hoặc key) toggleBtn?.addEventListener("click", async () => { if (isVisible(formBid)) { formBid.style.display = "none"; } else if (isVisible(formKey)) { formKey.style.display = "none"; } else { const currentKey = await getKey(); if (!currentKey) { showKey(); } else { showBid(); } } }); // Nhấn vào icon key để chuyển sang form-key keyBtn?.addEventListener("click", () => { showKey(); }); }; const handleChangeTitleButton = (result, formElements) => { if (result) { formElements.createBtn.textContent = "Update"; } else { formElements.createBtn.textContent = "Create"; } }; const handleSaveKey = () => { const form = document.querySelector("#form-key form"); if (!form) return; form.addEventListener("submit", async (e) => { e.preventDefault(); const inputKey = form.querySelector("#key"); if (!inputKey) return; const keyValue = inputKey.value.trim(); if (!keyValue) { alert("Please enter a key"); return; } // Lưu vào chrome.storage.local chrome.storage.local.set({ key: keyValue }, async () => { alert("Key saved successfully!"); showBid(); if (!isValidModel()) return; await showInfo(); }); }); }; const isValidModel = () => { const currentUrl = window.location.href; const model = extractModelId(currentUrl); return !!model; }; const createInfoColumn = (data, formElements) => { const inputsContainer = document.querySelector("#bid-extension .inputs"); const urlCol = document.querySelector("#url-col"); if (!inputsContainer || !urlCol) return; // 1. Thêm ID và Name vào đầu inputsContainer const otherEls = `