Spaces:
Running
Running
Upload folder using huggingface_hub
Browse files- index.html +155 -15
index.html
CHANGED
|
@@ -4,10 +4,11 @@
|
|
| 4 |
<head>
|
| 5 |
<meta charset="UTF-8">
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 7 |
-
<title>AI Prompt Gen | E-Commerce Asset System v4.
|
| 8 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 9 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 10 |
-
<link
|
|
|
|
| 11 |
rel="stylesheet">
|
| 12 |
<style>
|
| 13 |
:root {
|
|
@@ -170,6 +171,10 @@
|
|
| 170 |
font-size: 1rem;
|
| 171 |
cursor: pointer;
|
| 172 |
transition: background-color 0.2s, transform 0.1s;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
}
|
| 174 |
|
| 175 |
button.btn-primary:hover {
|
|
@@ -407,7 +412,7 @@
|
|
| 407 |
<path d="M12 12l-2-2"></path>
|
| 408 |
<path d="M12 16l-2-2"></path>
|
| 409 |
</svg>
|
| 410 |
-
PromptGen AI v4.
|
| 411 |
</div>
|
| 412 |
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with
|
| 413 |
anycoder</a>
|
|
@@ -437,7 +442,10 @@
|
|
| 437 |
<p class="helper-text">Use commas, slashes, or + to separate (e.g., Verde, Cáqui, White).</p>
|
| 438 |
</div>
|
| 439 |
|
| 440 |
-
<button class="btn-primary" id="generateBtn">
|
|
|
|
|
|
|
|
|
|
| 441 |
</aside>
|
| 442 |
|
| 443 |
<!-- Output Section -->
|
|
@@ -680,16 +688,6 @@
|
|
| 680 |
}
|
| 681 |
}
|
| 682 |
|
| 683 |
-
if (template.id === 'detail_2' && data.hasGifts) {
|
| 684 |
-
// Logic: DELETE PROMOTIONAL_OFFER logic (use Product Name)
|
| 685 |
-
// Since Block 2 is a macro shot, it doesn't inherently have text.
|
| 686 |
-
// We ensure the prompt focuses purely on the product material/name context.
|
| 687 |
-
// The prompt instruction says "Display only Product Name".
|
| 688 |
-
// We will append a clarification to ensure no promo text is implied if it were.
|
| 689 |
-
// (Since the base template doesn't have promo text, we leave it mostly as is,
|
| 690 |
-
// but we ensure we don't inject promo text later).
|
| 691 |
-
}
|
| 692 |
-
|
| 693 |
// --- STEP 4: TEMPLATE INJECTION ---
|
| 694 |
|
| 695 |
// 1. Product Name
|
|
@@ -705,4 +703,146 @@
|
|
| 705 |
if (data.material === 'Cotton') text = text.replace(/\bLinen\b/gi, 'Cotton');
|
| 706 |
|
| 707 |
// 3. Quantity
|
| 708 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
<head>
|
| 5 |
<meta charset="UTF-8">
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 7 |
+
<title>AI Prompt Gen | E-Commerce Asset System v4.8</title>
|
| 8 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 9 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 10 |
+
<link
|
| 11 |
+
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap"
|
| 12 |
rel="stylesheet">
|
| 13 |
<style>
|
| 14 |
:root {
|
|
|
|
| 171 |
font-size: 1rem;
|
| 172 |
cursor: pointer;
|
| 173 |
transition: background-color 0.2s, transform 0.1s;
|
| 174 |
+
display: flex;
|
| 175 |
+
justify-content: center;
|
| 176 |
+
align-items: center;
|
| 177 |
+
gap: 0.5rem;
|
| 178 |
}
|
| 179 |
|
| 180 |
button.btn-primary:hover {
|
|
|
|
| 412 |
<path d="M12 12l-2-2"></path>
|
| 413 |
<path d="M12 16l-2-2"></path>
|
| 414 |
</svg>
|
| 415 |
+
PromptGen AI v4.8
|
| 416 |
</div>
|
| 417 |
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with
|
| 418 |
anycoder</a>
|
|
|
|
| 442 |
<p class="helper-text">Use commas, slashes, or + to separate (e.g., Verde, Cáqui, White).</p>
|
| 443 |
</div>
|
| 444 |
|
| 445 |
+
<button class="btn-primary" id="generateBtn">
|
| 446 |
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-6.219-8.56"></path></svg>
|
| 447 |
+
Generate Prompts
|
| 448 |
+
</button>
|
| 449 |
</aside>
|
| 450 |
|
| 451 |
<!-- Output Section -->
|
|
|
|
| 688 |
}
|
| 689 |
}
|
| 690 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 691 |
// --- STEP 4: TEMPLATE INJECTION ---
|
| 692 |
|
| 693 |
// 1. Product Name
|
|
|
|
| 703 |
if (data.material === 'Cotton') text = text.replace(/\bLinen\b/gi, 'Cotton');
|
| 704 |
|
| 705 |
// 3. Quantity
|
| 706 |
+
text = text.replace(/5 pairs/g, `${data.totalQuantity} pairs`);
|
| 707 |
+
text = text.replace(/exactly 5 pairs/g, `exactly ${data.totalQuantity} pairs`);
|
| 708 |
+
text = text.replace(/exactly 5 identical/g, `exactly ${data.totalQuantity} identical`);
|
| 709 |
+
text = text.replace(/5 identical pairs/g, `${data.totalQuantity} identical pairs`);
|
| 710 |
+
|
| 711 |
+
// 4. Colors (The complex replacement)
|
| 712 |
+
// We replace the hardcoded list in the templates with the actual list
|
| 713 |
+
// Hardcoded patterns found in templates: "Green, Khaki, White, Black, and Beige" or "Green (Verde), Khaki (Cáki)..."
|
| 714 |
+
|
| 715 |
+
// Simple replacement for the list format "Green, Khaki, White, Black, and Beige"
|
| 716 |
+
text = text.replace(/Green, Khaki, White, Black, and Beige/g, data.colorListString);
|
| 717 |
+
|
| 718 |
+
// Replacement for descriptive format "Green (Verde), Khaki (Cáki), White (Branco), Black (Preto), and Beige"
|
| 719 |
+
// This requires mapping back, but for simplicity we replace the whole segment with the generated list
|
| 720 |
+
text = text.replace(/Green \(Verde\), Khaki \(Cáki\), White \(Branco\), Black \(Preto\), and Beige/gi, data.colorListString);
|
| 721 |
+
|
| 722 |
+
// Generic single color replacement (Beige, beige color)
|
| 723 |
+
if (template.type === "SINGLE") {
|
| 724 |
+
text = text.replace(/\bbeige color\b/gi, `${assignedColor} color`);
|
| 725 |
+
text = text.replace(/\bnatural beige\b/gi, `natural ${assignedColor}`);
|
| 726 |
+
text = text.replace(/\bcolor is natural beige\b/gi, `color is natural ${assignedColor}`);
|
| 727 |
+
}
|
| 728 |
+
|
| 729 |
+
return {
|
| 730 |
+
id: template.id,
|
| 731 |
+
title: template.title,
|
| 732 |
+
type: template.type,
|
| 733 |
+
content: text
|
| 734 |
+
};
|
| 735 |
+
});
|
| 736 |
+
}
|
| 737 |
+
|
| 738 |
+
// --- UI RENDERING & INTERACTION ---
|
| 739 |
+
|
| 740 |
+
function renderResults(results) {
|
| 741 |
+
const grid = document.getElementById('resultsGrid');
|
| 742 |
+
const statusBadge = document.getElementById('statusBadge');
|
| 743 |
+
|
| 744 |
+
grid.innerHTML = ''; // Clear previous results
|
| 745 |
+
|
| 746 |
+
if (!results || results.length === 0) {
|
| 747 |
+
grid.innerHTML = `
|
| 748 |
+
<div class="empty-state">
|
| 749 |
+
<div class="empty-icon">⚡</div>
|
| 750 |
+
<h3>No Results</h3>
|
| 751 |
+
<p>Could not generate prompts. Check your input.</p>
|
| 752 |
+
</div>
|
| 753 |
+
`;
|
| 754 |
+
statusBadge.textContent = "Error";
|
| 755 |
+
statusBadge.style.color = "var(--danger)";
|
| 756 |
+
return;
|
| 757 |
+
}
|
| 758 |
+
|
| 759 |
+
statusBadge.textContent = `Generated ${results.length} prompts`;
|
| 760 |
+
statusBadge.style.color = "var(--accent)";
|
| 761 |
+
|
| 762 |
+
results.forEach((res, index) => {
|
| 763 |
+
const card = document.createElement('div');
|
| 764 |
+
card.className = 'card';
|
| 765 |
+
card.style.animationDelay = `${index * 50}ms`; // Staggered animation
|
| 766 |
+
|
| 767 |
+
card.innerHTML = `
|
| 768 |
+
<div class="card-header">
|
| 769 |
+
<div class="card-title">
|
| 770 |
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>
|
| 771 |
+
${res.title}
|
| 772 |
+
</div>
|
| 773 |
+
<span class="card-type">${res.type}</span>
|
| 774 |
+
</div>
|
| 775 |
+
<div class="card-content">${escapeHtml(res.content)}</div>
|
| 776 |
+
<div class="card-actions">
|
| 777 |
+
<button class="btn-copy" onclick="copyText('${res.id}')">
|
| 778 |
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
|
| 779 |
+
Copy
|
| 780 |
+
</button>
|
| 781 |
+
</div>
|
| 782 |
+
`;
|
| 783 |
+
grid.appendChild(card);
|
| 784 |
+
});
|
| 785 |
+
}
|
| 786 |
+
|
| 787 |
+
// Helper to prevent XSS when displaying text
|
| 788 |
+
function escapeHtml(text) {
|
| 789 |
+
const map = {
|
| 790 |
+
'&': '&',
|
| 791 |
+
'<': '<',
|
| 792 |
+
'>': '>',
|
| 793 |
+
'"': '"',
|
| 794 |
+
"'": '''
|
| 795 |
+
};
|
| 796 |
+
return text.replace(/[&<>"']/g, function(m) { return map[m]; });
|
| 797 |
+
}
|
| 798 |
+
|
| 799 |
+
// Global store for copy function
|
| 800 |
+
let generatedResults = [];
|
| 801 |
+
|
| 802 |
+
function copyText(id) {
|
| 803 |
+
const item = generatedResults.find(r => r.id === id);
|
| 804 |
+
if (item) {
|
| 805 |
+
navigator.clipboard.writeText(item.content).then(() => {
|
| 806 |
+
showToast();
|
| 807 |
+
}).catch(err => {
|
| 808 |
+
console.error('Failed to copy: ', err);
|
| 809 |
+
});
|
| 810 |
+
}
|
| 811 |
+
}
|
| 812 |
+
|
| 813 |
+
function showToast() {
|
| 814 |
+
const toast = document.getElementById('toast');
|
| 815 |
+
toast.classList.add('show');
|
| 816 |
+
setTimeout(() => {
|
| 817 |
+
toast.classList.remove('show');
|
| 818 |
+
}, 3000);
|
| 819 |
+
}
|
| 820 |
+
|
| 821 |
+
// --- EVENT LISTENERS ---
|
| 822 |
+
document.addEventListener('DOMContentLoaded', () => {
|
| 823 |
+
const generateBtn = document.getElementById('generateBtn');
|
| 824 |
+
const productNameInput = document.getElementById('productName');
|
| 825 |
+
const colorListInput = document.getElementById('colorList');
|
| 826 |
+
|
| 827 |
+
generateBtn.addEventListener('click', () => {
|
| 828 |
+
const pName = productNameInput.value;
|
| 829 |
+
const cList = colorListInput.value;
|
| 830 |
+
|
| 831 |
+
if (!pName.trim()) {
|
| 832 |
+
alert("Please enter a product name.");
|
| 833 |
+
return;
|
| 834 |
+
}
|
| 835 |
+
|
| 836 |
+
// Execute Logic
|
| 837 |
+
const data = extractData(pName, cList);
|
| 838 |
+
generatedResults = processTemplates(data); // Store for copy function
|
| 839 |
+
|
| 840 |
+
// Render
|
| 841 |
+
renderResults(generatedResults);
|
| 842 |
+
});
|
| 843 |
+
});
|
| 844 |
+
|
| 845 |
+
</script>
|
| 846 |
+
</body>
|
| 847 |
+
|
| 848 |
+
</html>
|