ΠΠΎΡΡΡΠΏΠ½ΡΠ΅ ΠΌΠ°ΡΠΊΠ΅ΡΠΏΠ»Π΅ΠΉΡΡ
diff --git a/frontend/js/app.js b/frontend/js/app.js
index 76aef3d..ab5ed8d 100644
--- a/frontend/js/app.js
+++ b/frontend/js/app.js
@@ -161,10 +161,13 @@ async function loadDashboard() {
storesTbody.innerHTML = '';
(data.stores || []).forEach(s => {
const tr = document.createElement('tr');
+ const oosClass = s.days_left < 7 ? 'color: var(--color-error); font-weight: bold;' : '';
tr.innerHTML = `
${s.name} |
${s.platform} |
β Online |
+ ${s.stock} |
+ ${s.days_left} Π΄Π½. |
${(s.daily_sales || 0).toLocaleString()} β½ |
`;
storesTbody.appendChild(tr);
@@ -273,10 +276,146 @@ function initTabs() {
if(target === 'content-section') loadReferences();
if(target === 'finance-section') { /* No initial load */ }
if(target === 'generator-section') { /* No initial load */ }
+ if(target === 'analytics-section') { /* No initial load */ }
+ if(target === 'repricer-section') loadRepricerRules();
});
});
}
+async function loadRepricerRules() {
+ const table = document.getElementById('repricer-table').querySelector('tbody');
+ try {
+ const token = localStorage.getItem('token');
+ const res = await fetch('http://localhost:5000/api/repricer/rules', {
+ headers: { 'Authorization': `Bearer ${token}` }
+ });
+ const rules = await res.json();
+
+ table.innerHTML = '';
+ rules.forEach(r => {
+ const tr = document.createElement('tr');
+ tr.innerHTML = `
+ ${r.product_name} ${r.sku} |
+ ${r.min_price} - ${r.max_price} β½ |
+ ${r.current_price ? r.current_price + ' β½' : 'β'} |
+ ${r.last_run ? new Date(r.last_run).toLocaleString() : 'ΠΠΈΠΊΠΎΠ³Π΄Π°'} |
+ ${r.is_active ? 'ΠΠΊΡΠΈΠ²Π½ΠΎ' : 'ΠΠ°ΡΠ·Π°'} |
+ `;
+ table.appendChild(tr);
+ });
+ } catch (err) {
+ console.error('Error loading repricer rules:', err);
+ }
+}
+
+document.getElementById('repricer-form').addEventListener('submit', async (e) => {
+ e.preventDefault();
+ const fd = new FormData(e.target);
+ const data = Object.fromEntries(fd.entries());
+ data.is_active = true;
+
+ try {
+ const token = localStorage.getItem('token');
+ await fetch('http://localhost:5000/api/repricer/rules', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${token}`
+ },
+ body: JSON.stringify(data)
+ });
+ showToast('ΠΡΠ°Π²ΠΈΠ»ΠΎ ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΎ', 'success');
+ loadRepricerRules();
+ e.target.reset();
+ } catch (err) {
+ alert('ΠΡΠΈΠ±ΠΊΠ° ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΡ');
+ }
+});
+
+document.getElementById('run-repricer-btn').addEventListener('click', async () => {
+ const btn = document.getElementById('run-repricer-btn');
+ btn.disabled = true;
+ btn.innerHTML = ' ΠΠ±Π½ΠΎΠ²Π»ΡΡ...';
+ if (window.lucide) lucide.createIcons();
+
+ try {
+ const token = localStorage.getItem('token');
+ const res = await fetch('http://localhost:5000/api/repricer/run', {
+ method: 'POST',
+ headers: { 'Authorization': `Bearer ${token}` }
+ });
+ const data = await res.json();
+
+ showToast(`ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΎ ${data.updates.length} ΡΠ΅Π½`, 'success');
+ loadRepricerRules();
+ } catch (err) {
+ alert('ΠΡΠΈΠ±ΠΊΠ° ΠΏΡΠΈ Π·Π°ΠΏΡΡΠΊΠ΅ ΡΠ΅ΠΏΡΠ°ΠΉΠ·Π΅ΡΠ°');
+ } finally {
+ btn.disabled = false;
+ btn.innerHTML = ' ΠΠ±Π½ΠΎΠ²ΠΈΡΡ ΡΠ΅Π½Ρ ΡΠ΅ΠΉΡΠ°Ρ';
+ if (window.lucide) lucide.createIcons();
+ }
+});
+
+document.getElementById('ai-analyze-comp-btn').addEventListener('click', async () => {
+ const myDesc = document.getElementById('my-desc-input').value;
+ const compDesc = document.getElementById('comp-desc-input').value;
+
+ if (!compDesc) {
+ alert('ΠΠ²Π΅Π΄ΠΈΡΠ΅ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΠΊΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠ°');
+ return;
+ }
+
+ const btn = document.getElementById('ai-analyze-comp-btn');
+ const originalHTML = btn.innerHTML;
+ btn.disabled = true;
+ btn.innerHTML = ' ΠΠ½Π°Π»ΠΈΠ·ΠΈΡΡΡ ΡΡΠ½ΠΎΠΊ...';
+ if (window.lucide) lucide.createIcons();
+
+ try {
+ const token = localStorage.getItem('token');
+ const res = await fetch('http://localhost:5000/api/ai/analyze-competitor', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${token}`
+ },
+ body: JSON.stringify({ my_desc: myDesc, comp_desc: compDesc })
+ });
+ const data = await res.json();
+
+ if (data.error) throw new Error(data.error);
+
+ document.getElementById('insight-result').classList.remove('hidden');
+ document.getElementById('insight-win-phrase').innerText = data.win_phrase;
+ document.getElementById('insight-strategy').innerText = data.strategy;
+
+ const wList = document.getElementById('insight-weakness');
+ wList.innerHTML = '';
+ data.competitor_weakness.forEach(w => {
+ const li = document.createElement('li');
+ li.innerText = w;
+ wList.appendChild(li);
+ });
+
+ const aList = document.getElementById('insight-advantages');
+ aList.innerHTML = '';
+ data.my_advantages.forEach(a => {
+ const li = document.createElement('li');
+ li.innerText = a;
+ aList.appendChild(li);
+ });
+
+ showToast('ΠΠ½Π°Π»ΠΈΠ· Deep Insight Π·Π°Π²Π΅ΡΡΠ΅Π½!', 'success');
+ } catch (err) {
+ alert(err.message);
+ } finally {
+ btn.disabled = false;
+ btn.innerHTML = originalHTML;
+ if (window.lucide) lucide.createIcons();
+ }
+});
+
document.getElementById('ai-gen-card-btn').addEventListener('click', async () => {
const title = document.getElementById('gen-title-input').value;
if (!title) {