const $ = (sel, root = document) => root.querySelector(sel); const root = $('#app'); const TOKEN_KEY = 'andishkade_panel_token'; const getToken = () => localStorage.getItem(TOKEN_KEY); const setToken = (t) => localStorage.setItem(TOKEN_KEY, t); const clearToken = () => localStorage.removeItem(TOKEN_KEY); const CATEGORIES = ['بازار جهانی', 'سیاست‌گذاری', 'انرژی و ESG', 'صادرات', 'تولید داخلی', 'ریسک و بحران']; const TYPES = [ { value: 'quarterly', label: 'فصلی' }, { value: 'flash', label: 'فلش' }, { value: 'risk', label: 'هشدار ریسک' }, { value: 'free', label: 'رایگان' }, { value: 'special', label: 'ویژه' }, ]; async function api(path, { method = 'GET', body, isForm = false } = {}) { const headers = {}; const token = getToken(); if (token) headers.Authorization = `Bearer ${token}`; if (body && !isForm) headers['Content-Type'] = 'application/json'; const res = await fetch(path, { method, headers, body: isForm ? body : (body ? JSON.stringify(body) : undefined), }); if (res.status === 401) { clearToken(); renderLogin('نیاز به ورود مجدد است'); throw new Error('unauthorized'); } if (!res.ok) { const text = await res.text(); throw new Error(text || res.statusText); } if (res.status === 204) return null; return res.json(); } function renderLogin(errorMsg = '') { root.innerHTML = `

ورود به پنل مدیریت

اندیشکده فولاد

${errorMsg ? `
${errorMsg}
` : ''}
`; $('#loginForm').addEventListener('submit', async (e) => { e.preventDefault(); const fd = new FormData(e.target); try { const data = await api('/api/auth/login', { method: 'POST', body: { username: fd.get('username'), password: fd.get('password') }, }); setToken(data.token); renderList(); } catch { renderLogin('نام کاربری یا رمز عبور اشتباه است'); } }); } async function renderList() { root.innerHTML = `
پنل اندیشکده فولاد

مطالب

در حال بارگذاری…

`; $('#logoutBtn').addEventListener('click', () => { clearToken(); renderLogin(); }); $('#newBtn').addEventListener('click', () => renderEditor(null)); try { const items = await api('/api/articles?limit=200'); if (!items.length) { $('#list').innerHTML = `

هنوز مطلبی ثبت نشده است.

`; return; } $('#list').innerHTML = items.map((a) => `
${a.featured ? 'ویژه' : ''} ${a.category ? `${a.category}` : ''} ${a.publishDate ? `${a.publishDate}` : ''}

${a.title}

${a.summary || ''}

`).join(''); $('#list').addEventListener('click', async (e) => { const btn = e.target.closest('button[data-action]'); if (!btn) return; const row = btn.closest('.row'); const id = row.dataset.id; if (btn.dataset.action === 'edit') { const a = await api(`/api/articles/${id}`); renderEditor(a); } else if (btn.dataset.action === 'delete') { if (!confirm('این مطلب حذف شود؟')) return; await api(`/api/articles/${id}`, { method: 'DELETE' }); renderList(); } }); } catch (err) { console.error(err); $('#list').innerHTML = `

خطا در بارگذاری مطالب.

`; } } function renderEditor(article) { const a = article || { title: '', category: '', type: '', author: '', authorRole: '', authorInitial: '', publishDate: '', pages: 0, price: 0, isFree: true, summary: '', body: '', coverImage: '', tags: [], featured: false, }; const isEdit = !!article; root.innerHTML = `
${isEdit ? 'ویرایش مطلب' : 'مطلب جدید'}
`; $('#backBtn').addEventListener('click', () => renderList()); $('#coverFile').addEventListener('change', async (e) => { const file = e.target.files?.[0]; if (!file) return; const fd = new FormData(); fd.append('file', file); try { const { url } = await api('/api/uploads', { method: 'POST', body: fd, isForm: true }); $('input[name="coverImage"]').value = url; $('#coverPreview').src = url; } catch (err) { alert('آپلود ناموفق بود: ' + err.message); } }); $('#editorForm').addEventListener('submit', async (e) => { e.preventDefault(); const fd = new FormData(e.target); const tagsRaw = String(fd.get('tags') || '').split(/[,،]/).map(s => s.trim()).filter(Boolean); const payload = { title: fd.get('title'), category: fd.get('category') || null, type: fd.get('type') || null, author: fd.get('author') || null, authorRole: fd.get('authorRole') || null, authorInitial: fd.get('authorInitial') || null, publishDate: fd.get('publishDate') || null, pages: Number(fd.get('pages') || 0), price: Number(fd.get('price') || 0), isFree: fd.get('isFree') === 'on', featured: fd.get('featured') === 'on', summary: fd.get('summary') || null, body: fd.get('body') || null, coverImage: fd.get('coverImage') || null, tags: tagsRaw, }; try { if (isEdit) { await api(`/api/articles/${article.id}`, { method: 'PUT', body: payload }); } else { await api('/api/articles', { method: 'POST', body: payload }); } renderList(); } catch (err) { alert('ذخیره ناموفق بود: ' + err.message); } }); } function escapeAttr(s) { return String(s ?? '').replace(/&/g, '&').replace(/"/g, '"').replace(//g, '>'); } if (getToken()) renderList(); else renderLogin();