From 21f82d273dfe08a2c2429035a09b9a1f7c07eb90 Mon Sep 17 00:00:00 2001 From: numex-admin Date: Thu, 10 Sep 2026 08:59:24 +0000 Subject: [PATCH] =?UTF-8?q?Numex=20yay=C4=B1n:=20public/app.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/app.js | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 public/app.js diff --git a/public/app.js b/public/app.js new file mode 100644 index 0000000..d480572 --- /dev/null +++ b/public/app.js @@ -0,0 +1,172 @@ +// Numex Depo Yönetim Sistemi - Frontend mantığı +const api = { + list: (p) => fetch('/api/' + p).then(r => r.json()), + post: (p, body) => fetch('/api/' + p, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body) + }).then(async r => ({ ok: r.ok, veri: await r.json() })), + del: (p) => fetch('/api/' + p, { method: 'DELETE' }).then(r => r.json()) +}; + +// --- Sekme geçişleri --- +document.querySelectorAll('.sekm').forEach(btn => { + btn.addEventListener('click', () => { + document.querySelectorAll('.sekm').forEach(b => b.classList.remove('secili')); + document.querySelectorAll('.panel').forEach(p => p.classList.remove('aktif')); + btn.classList.add('secili'); + document.getElementById('sekme-' + btn.dataset.sekme).classList.add('aktif'); + yenile(); + }); +}); + +// --- Evrensel yenileme --- +function yenile() { + lokasyonlariYukle(); + urunleriYukle(); + stoguYukle(); + gecmisiYukle(); + uyarilariYukle(); +} + +// --- Lokasyonlar --- +async function lokasyonlariYukle() { + const lokasyonlar = await api.list('lokasyonlar'); + const t = document.getElementById('lokasyon-tablo'); + t.innerHTML = lokasyonlar.length ? lokasyonlar.map(l => ` + + ${l.id}${l.ad}${l.sehir || '-'} + ${new Date(l.olusturuldu).toLocaleDateString('tr-TR')} + + `).join('') : 'Henüz lokasyon yok'; + + // Transfer form dropdownları + durumlariDoldur('transfer-kaynak', lokasyonlar); + durumlariDoldur('transfer-hedef', lokasyonlar); +} + +function durumlariDoldur(id, lokasyonlar) { + const s = document.getElementById(id); + const mevcut = s.value; + s.innerHTML = lokasyonlar.map(l => ``).join(''); + if (lokasyonlar.some(l => l.id === Number(mevcut))) s.value = mevcut; +} + +async function lokasyonSil(id) { + if (!confirm('Bu lokasyon silinsin mi?')) return; + await api.del('lokasyonlar/' + id); + yenile(); +} + +document.getElementById('lokasyon-form').addEventListener('submit', async (e) => { + e.preventDefault(); + await api.post('lokasyonlar', { + ad: document.getElementById('lokasyon-ad').value, + sehir: document.getElementById('lokasyon-sehir').value + }); + e.target.reset(); + yenile(); +}); + +// --- Ürünler --- +async function urunleriYukle() { + const urunler = await api.list('urunler'); + const t = document.getElementById('urun-tablo'); + t.innerHTML = urunler.length ? urunler.map(u => ` + + ${u.id}${u.ad}${u.birim} + ${u.dusukStokEsigi} + + `).join('') : 'Henüz ürün yok'; + + const s = document.getElementById('transfer-urun'); + s.innerHTML = urunler.map(u => ``).join(''); +} + +async function urunSil(id) { + if (!confirm('Bu ürün silinsin mi?')) return; + await api.del('urunler/' + id); + yenile(); +} + +document.getElementById('urun-form').addEventListener('submit', async (e) => { + e.preventDefault(); + await api.post('urunler', { + ad: document.getElementById('urun-ad').value, + birim: document.getElementById('urun-birim').value, + dusukStokEsigi: document.getElementById('urun-esik').value + }); + e.target.reset(); + yenile(); +}); + +// --- Stok --- +async function stoguYukle() { + const veri = await api.list('stok'); + const g = document.getElementById('stok-gorunum'); + if (!veri.length) { g.innerHTML = '

Lokasyon ekleyin ve stok girişi yapın.

'; return; } + + g.innerHTML = veri.map(l => ` +
+

🏬 ${l.lokasyonAd} (${l.sehir || 'Şehir yok'})

+ + + + ${l.stok.length ? l.stok.map(k => { + const dusuk = k.miktar <= k.dusukStokEsigi; + return ` + + + `; + }).join('') : ''} + +
ÜrünBirimMiktarDurum
${k.urunAd}${k.birim}${k.miktar}${dusuk ? '⬇ Düşük stok' : '✓ Yeterli'}
Bu lokasyonda stok yok
+
`).join(''); +} + +// --- Transfer --- +document.getElementById('transfer-form').addEventListener('submit', async (e) => { + e.preventDefault(); + const mesaj = document.getElementById('transfer-mesaj'); + const sonuc = await api.post('transferler', { + kaynakId: document.getElementById('transfer-kaynak').value, + hedefId: document.getElementById('transfer-hedef').value, + urunId: document.getElementById('transfer-urun').value, + miktar: document.getElementById('transfer-miktar').value + }); + mesaj.className = 'mesaj ' + (sonuc.ok ? 'ok' : 'hata'); + mesaj.textContent = sonuc.ok + ? '✅ Transfer başarılı!' + : (sonuc.veri.hata || 'Transfer yapılamadı') + (Array.isArray(sonuc.veri.hata) ? '' : ''); + if (sonuc.ok) e.target.reset(); + yenile(); +}); + +// --- Transfer geçmişi --- +async function gecmisiYukle() { + if (!document.getElementById('sekme-gecmis').classList.contains('aktif')) return; + const veri = await api.list('transferler'); + const t = document.getElementById('gecmis-tablo'); + t.innerHTML = veri.length ? veri.map(g => ` + + ${new Date(g.tarih).toLocaleString('tr-TR')} + ${g.urunAd}${g.kaynakAd}→ + ${g.hedefAd}${g.miktar} + `).join('') : 'Henüz transfer yapılmadı'; +} + +// --- Düşük stok uyarıları --- +async function uyarilariYukle() { + if (!document.getElementById('sekme-uyari').classList.contains('aktif')) return; + const veri = await api.list('stok/uyari/dusuk'); + const t = document.getElementById('uyari-tablo'); + t.innerHTML = veri.length ? veri.map(u => ` + + ${u.lokasyonAd}${u.urunAd} + ${u.miktar}${u.dusukStokEsigi} + ⚠ Stok az + `).join('') : '🎉 Tüm stok seviyeleri yeterli'; +} + +// Başlangıç +yenile();