index.html
<!DOCTYPE html>
<html lang=”fa” dir=”rtl”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<title>مایسا خانه – مدیریت موجودی</title>
<link rel=”stylesheet” href=”/style.css”>
</head>
<body>
<div id=”toast” class=”toast”></div>
<!– SIDEBAR –>
<div class=”sidebar”>
<div class=”sidebar-header”>
<div class=”logo”>🏭</div>
<div class=”brand”>مایسا خانه</div>
</div>
<nav class=”nav”>
<div class=”nav-item active” onclick=”showPage(‘dashboard’)”>📊 داشبورد</div>
<div class=”nav-item” onclick=”showPage(‘inventory’)”>📦 موجودی</div>
<div class=”nav-item” onclick=”showPage(‘sales’)”>🛒 فروش</div>
<div class=”nav-item” onclick=”showPage(‘reports’)”>📈 گزارشها</div>
<div class=”nav-item” onclick=”showPage(‘warnings’)”>
⚠️ هشدارها
<span id=”warningBadge” class=”badge” style=”display:none”></span>
</div>
<div class=”nav-item” onclick=”showPage(‘transfer’)”>🔄 انتقال موجودی</div>
<div class=”nav-item” onclick=”showPage(‘products_manage’)”>⚙️ مدیریت کالا</div>
<div class=”nav-item” data-page=”users_manage” onclick=”showPage(‘users_manage’)”>👥 مدیریت کاربران</div>
<div class=”nav-item” onclick=”showPage(‘tickets’)”>
🎫 تیکتها
<span id=”ticketBadge” class=”badge” style=”display:none”></span>
</div>
<div class=”nav-item” onclick=”showPage(‘workflow’)”>🔁 گردش کار</div>
</nav>
<div class=”sidebar-footer”>
<div id=”currentDate”></div>
<div id=”userInfo” style=”margin-top:0.5rem;padding-top:0.5rem;border-top:1px solid #333;font-size:0.8rem;color:#ccc;”>
<div id=”userDetails”></div>
<button id=”logoutBtn” class=”btn” style=”width:100%;margin-top:0.5rem;font-size:0.75rem;” onclick=”Auth.logout()”>خروج</button>
</div>
</div>
</div>
<!– MAIN –>
<div class=”main”>
<!– DASHBOARD –>
<div id=”page-dashboard” class=”page active”>
<div class=”page-header”><h1>داشبورد</h1></div>
<div id=”dashboardCards” class=”cards-grid”></div>
<div class=”charts-grid”>
<div class=”chart-box”>
<h3>فروش ماهانه</h3>
<canvas id=”monthlyChart” style=”width:100%;”></canvas>
</div>
<div class=”chart-box”>
<h3>فروش شعب</h3>
<canvas id=”branchChart” style=”width:100%;”></canvas>
</div>
</div>
<div class=”section”>
<h3>هشدارهای موجودی</h3>
<ul id=”dashWarningList”></ul>
</div>
</div>
<!– INVENTORY –>
<div id=”page-inventory” class=”page”>
<div class=”page-header”>
<h1>موجودی انبار</h1>
</div>
<div class=”search-bar” style=”display:flex;gap:0.75rem;flex-wrap:wrap;margin-bottom:1.2rem;”>
<input
type=”text”
id=”inv-search”
placeholder=”🔍 جستجوی کالا…”
oninput=”renderInventory()”
style=”flex:1;min-width:180px;”
>
<select id=”inv-branch” onchange=”renderInventory()”>
<option value=””>همه شعب</option>
<option value=”gisha”>گیشا</option>
<option value=”saadat”>سعادتآباد</option>
<option value=”poonak”>پونک</option>
<option value=”warehouse”>انبار مرکزی</option>
</select>
<select id=”inv-status” onchange=”renderInventory()”>
<option value=””>همه وضعیتها</option>
<option value=”ok”>موجود</option>
<option value=”low”>موجودی کم</option>
<option value=”zero”>ناموجود</option>
</select>
</div>
<div id=”inv-cards-container”></div>
</div>
<!– SALES –>
<div id=”page-sales” class=”page”>
<div class=”page-header”>
<h1>فروش</h1>
<button class=”btn btn-primary” onclick=”document.getElementById(‘modalSale’).classList.add(‘open’)”>+ ثبت فروش</button>
</div>
<div id=”salesTable”></div>
</div>
<!– REPORTS –>
<div id=”page-reports” class=”page”>
<div class=”page-header”><h1>گزارشها</h1></div>
<div id=”reportsContent”></div>
</div>
<!– WARNINGS –>
<div id=”page-warnings” class=”page”>
<div class=”page-header”><h1>هشدارها</h1></div>
<div id=”warningsContent”></div>
</div>
<!– TRANSFER –>
<div id=”page-transfer” class=”page”>
<div class=”page-header”><h1>انتقال موجودی</h1></div>
<div class=”card” style=”max-width:480px;margin:0 auto;padding:1.5rem;”>
<label>کالا</label>
<select id=”tr-product” style=”width:100%;margin-bottom:1rem;” onchange=”updateTransferStockInfo()”></select>
<label>مبدأ</label>
<select id=”tr-from” style=”width:100%;margin-bottom:1rem;” onchange=”updateTransferStockInfo()”>
<option value=”gisha”>گیشا</option>
<option value=”saadat”>سعادتآباد</option>
<option value=”poonak”>پونک</option>
<option value=”warehouse”>انبار مرکزی</option>
</select>
<label>مقصد</label>
<select id=”tr-to” style=”width:100%;margin-bottom:1rem;”>
<option value=”gisha”>گیشا</option>
<option value=”saadat”>سعادتآباد</option>
<option value=”poonak”>پونک</option>
<option value=”warehouse”>انبار مرکزی</option>
</select>
<label>تعداد</label>
<input type=”number” id=”tr-qty” min=”1″ value=”1″ style=”width:100%;margin-bottom:1rem;”>
<div id=”tr-stock-info” style=”margin-bottom:1rem;color:#888;font-size:0.9rem;”></div>
<button class=”btn btn-primary” style=”width:100%;” onclick=”submitTransfer()”>انتقال</button>
</div>
<div style=”margin-top:2rem;”>
<h3>تاریخچه انتقالها</h3>
<div id=”transferHistory”></div>
</div>
</div>
<!– PRODUCTS MANAGE –>
<div id=”page-products_manage” class=”page”>
<div class=”page-header”>
<h1>مدیریت کالا</h1>
<button class=”btn btn-primary” onclick=”openAddProductModal()”>+ افزودن کالا</button>
<button class=”btn” onclick=”exportCSV()”>📥 خروجی CSV</button>
</div>
<table class=”table”>
<thead>
<tr>
<th>#</th><th>نام کالا</th><th>مدل</th><th>حداقل موجودی</th>
<th>قیمت</th><th>موجودی کل</th><th>ویرایش</th><th>حذف</th>
</tr>
</thead>
<tbody id=”manageProductsTable”></tbody>
</table>
</div>
<!– مدیریت کاربران –>
<div id=”page-users_manage” class=”page”>
<div class=”page-header”>
<h1>مدیریت کاربران</h1>
<button class=”btn btn-primary” onclick=”UsersManage.openUserModal()”>+ کاربر جدید</button>
</div>
<div class=”tabs” style=”display:flex;gap:0.5rem;margin-bottom:1.5rem;”>
<button class=”btn btn-primary” id=”tab-users-btn” onclick=”UsersManage.switchTab(‘users’)”>کاربران</button>
<button class=”btn” id=”tab-roles-btn” onclick=”UsersManage.switchTab(‘roles’)”>نقشها</button>
</div>
<div id=”tab-users”>
<div id=”usersList”></div>
</div>
<div id=”tab-roles” style=”display:none;”>
<div style=”margin-bottom:1rem;”>
<button class=”btn btn-primary” onclick=”UsersManage.openRoleModal()”>+ نقش جدید</button>
</div>
<div id=”rolesList”></div>
</div>
</div>
<!– TICKETS –>
<div id=”page-tickets” class=”page”>
<div class=”page-header”>
<h1>تیکتها</h1>
<button class=”btn btn-primary” onclick=”openNewTicketModal()”>+ تیکت جدید</button>
</div>
<div class=”search-bar” style=”display:flex;gap:0.75rem;flex-wrap:wrap;margin-bottom:1.2rem;”>
<select id=”ticket-filter-dept” onchange=”renderTickets()”>
<option value=””>همه دپارتمانها</option>
<option value=”warehouse”>انبار</option>
<option value=”sales”>فروش</option>
<option value=”production”>تولید</option>
<option value=”admin”>مدیریت</option>
</select>
<select id=”ticket-filter-status” onchange=”renderTickets()”>
<option value=””>همه وضعیتها</option>
<option value=”open”>باز</option>
<option value=”pending”>در انتظار</option>
<option value=”closed”>بسته</option>
</select>
</div>
<div id=”ticketsList”></div>
</div>
<!– WORKFLOW –>
<div id=”page-workflow” class=”page”>
<div class=”page-header”>
<h1>گردش کار</h1>
</div>
<div class=”tabs” style=”display:flex;gap:0.5rem;margin-bottom:1.5rem;”>
<button class=”btn btn-primary” id=”tab-orders-btn” onclick=”switchWorkflowTab(‘orders’)”>سفارشات جاری</button>
<button class=”btn” id=”tab-templates-btn” onclick=”switchWorkflowTab(‘templates’)”>قالبها</button>
</div>
<div id=”tab-orders”>
<div style=”margin-bottom:1rem;”>
<button class=”btn btn-primary” onclick=”openNewOrderModal()”>+ شروع سفارش جدید</button>
</div>
<div id=”ordersList”></div>
</div>
<div id=”tab-templates” style=”display:none;”>
<div style=”margin-bottom:1rem;”>
<button class=”btn btn-primary” onclick=”openNewTemplateModal()”>+ قالب جدید</button>
</div>
<div id=”templatesList”></div>
</div>
</div>
</div><!– /main –>
<!– MODAL: افزودن/ویرایش کالا –>
<div id=”productModal” class=”modal”>
<div class=”modal-box”>
<div class=”modal-header”>
<h2 id=”productModalTitle”>افزودن کالا</h2>
<button class=”close-btn” onclick=”closeModal(‘productModal’)”>✕</button>
</div>
<div class=”modal-body”>
<input type=”hidden” id=”pm_id”>
<label>نام کالا</label>
<input type=”text” id=”pm_name”>
<label>مدل</label>
<input type=”text” id=”pm_model”>
<label>قیمت پایه (تومان)</label>
<input type=”number” id=”pm_price” min=”0″>
<label>حداقل موجودی هشدار</label>
<input type=”number” id=”pm_min” min=”0″ value=”5″>
<label>موجودی گیشا</label>
<input type=”number” id=”pm_gisha” min=”0″ value=”0″>
<label>موجودی سعادتآباد</label>
<input type=”number” id=”pm_saadat” min=”0″ value=”0″>
<label>موجودی پونک</label>
<input type=”number” id=”pm_poonak” min=”0″ value=”0″>
<label>موجودی انبار مرکزی</label>
<input type=”number” id=”pm_warehouse” min=”0″ value=”0″>
</div>
<div class=”modal-footer”>
<button class=”btn btn-primary” onclick=”saveProduct()”>ذخیره</button>
<button class=”btn” onclick=”closeModal(‘productModal’)”>انصراف</button>
</div>
</div>
</div>
<!– MODAL: ثبت فروش –>
<div id=”modalSale” class=”modal”>
<div class=”modal-box”>
<div class=”modal-header”>
<h2>ثبت فروش جدید</h2>
<button class=”close-btn” onclick=”closeModal(‘modalSale’)”>✕</button>
</div>
<div class=”modal-body”>
<label>کالا</label>
<select id=”saleProduct” class=”product-select” onchange=”onSaleProductChange()”></select>
<label>شعبه</label>
<select id=”saleBranch”>
<option value=”گیشا”>گیشا</option>
<option value=”سعادت آباد”>سعادتآباد</option>
<option value=”پونک”>پونک</option>
</select>
<label>تعداد</label>
<input type=”number” id=”saleQty” min=”1″ value=”1″>
<label>قیمت فروش (تومان)</label>
<input type=”number” id=”salePrice” min=”0″>
<label>تاریخ فروش</label>
<input type=”text” id=”saleDate” placeholder=”1404/01/15″ dir=”ltr”>
<label>توضیحات</label>
<input type=”text” id=”saleNote” placeholder=”اختیاری”>
</div>
<div class=”modal-footer”>
<button class=”btn btn-primary” onclick=”submitSale()”>ثبت</button>
<button class=”btn” onclick=”closeModal(‘modalSale’)”>انصراف</button>
</div>
</div>
</div>
<!– MODAL: تیکت جدید –>
<div id=”modalNewTicket” class=”modal”>
<div class=”modal-box”>
<div class=”modal-header”>
<h2>تیکت جدید</h2>
<button class=”close-btn” onclick=”closeModal(‘modalNewTicket’)”>✕</button>
</div>
<div class=”modal-body”>
<label>عنوان</label>
<input type=”text” id=”tk_title” placeholder=”عنوان تیکت”>
<label>دپارتمان مبدأ</label>
<select id=”tk_from_dept”>
<option value=”warehouse”>انبار</option>
<option value=”sales”>فروش</option>
<option value=”production”>تولید</option>
<option value=”admin”>مدیریت</option>
</select>
<label>دپارتمان مقصد</label>
<select id=”tk_to_dept”>
<option value=”warehouse”>انبار</option>
<option value=”sales”>فروش</option>
<option value=”production”>تولید</option>
<option value=”admin”>مدیریت</option>
</select>
<label>اولویت</label>
<select id=”tk_priority”>
<option value=”low”>کم</option>
<option value=”medium”>متوسط</option>
<option value=”high”>زیاد</option>
</select>
<label>متن</label>
<textarea id=”tk_body” rows=”4″ style=”width:100%;resize:vertical;”></textarea>
<label>پیوست (اختیاری)</label>
<input type=”file” id=”tk_attachment”>
</div>
<div class=”modal-footer”>
<button class=”btn btn-primary” onclick=”submitNewTicket()”>ارسال</button>
<button class=”btn” onclick=”closeModal(‘modalNewTicket’)”>انصراف</button>
</div>
</div>
</div>
<!– MODAL: جزئیات تیکت –>
<div id=”modalTicketDetail” class=”modal”>
<div class=”modal-box” style=”max-width:600px;”>
<div class=”modal-header”>
<h2 id=”tkd_title”>جزئیات تیکت</h2>
<button class=”close-btn” onclick=”closeModal(‘modalTicketDetail’)”>✕</button>
</div>
<div class=”modal-body”>
<div id=”tkd_meta” style=”color:#888;font-size:0.85rem;margin-bottom:1rem;”></div>
<div id=”tkd_messages” style=”max-height:300px;overflow-y:auto;margin-bottom:1rem;”></div>
<label>پاسخ</label>
<textarea id=”tkd_reply” rows=”3″ style=”width:100%;resize:vertical;”></textarea>
<label>پیوست (اختیاری)</label>
<input type=”file” id=”tkd_attachment”>
</div>
<div class=”modal-footer”>
<button class=”btn btn-primary” onclick=”submitTicketReply()”>ارسال پاسخ</button>
<button class=”btn btn-danger” onclick=”closeTicket()”>بستن تیکت</button>
<button class=”btn” onclick=”closeModal(‘modalTicketDetail’)”>انصراف</button>
</div>
</div>
</div>
<!– MODAL: سفارش جدید –>
<div id=”modalNewOrder” class=”modal”>
<div class=”modal-box”>
<div class=”modal-header”>
<h2>شروع سفارش جدید</h2>
<button class=”close-btn” onclick=”closeModal(‘modalNewOrder’)”>✕</button>
</div>
<div class=”modal-body”>
<label>عنوان سفارش</label>
<input type=”text” id=”ord_title” placeholder=”مثلاً: دوخت پرده سالن”>
<label>قالب گردش کار</label>
<select id=”ord_template”></select>
<label>توضیحات</label>
<textarea id=”ord_note” rows=”3″ style=”width:100%;resize:vertical;”></textarea>
</div>
<div class=”modal-footer”>
<button class=”btn btn-primary” onclick=”submitNewOrder()”>شروع</button>
<button class=”btn” onclick=”closeModal(‘modalNewOrder’)”>انصراف</button>
</div>
</div>
</div>
<!– MODAL: قالب جدید/ویرایش –>
<div id=”modalTemplate” class=”modal”>
<div class=”modal-box” style=”max-width:560px;”>
<div class=”modal-header”>
<h2 id=”tpl_modal_title”>قالب جدید</h2>
<button class=”close-btn” onclick=”closeModal(‘modalTemplate’)”>✕</button>
</div>
<div class=”modal-body”>
<input type=”hidden” id=”tpl_id”>
<label>نام قالب</label>
<input type=”text” id=”tpl_name” placeholder=”مثلاً: دوخت پرده”>
<label>توضیحات</label>
<input type=”text” id=”tpl_desc” placeholder=”اختیاری”>
<div style=”margin-top:1rem;”>
<div style=”display:flex;justify-content:space-between;align-items:center;margin-bottom:0.5rem;”>
<strong>مراحل</strong>
<button class=”btn” onclick=”addTemplateStep()”>+ افزودن مرحله</button>
</div>
<div id=”tpl_steps”></div>
</div>
</div>
<div class=”modal-footer”>
<button class=”btn btn-primary” onclick=”saveTemplate()”>ذخیره</button>
<button class=”btn” onclick=”closeModal(‘modalTemplate’)”>انصراف</button>
</div>
</div>
</div>
<!– MODAL: جزئیات سفارش –>
<div id=”modalOrderDetail” class=”modal”>
<div class=”modal-box” style=”max-width:580px;”>
<div class=”modal-header”>
<h2 id=”ord_detail_title”>جزئیات سفارش</h2>
<button class=”close-btn” onclick=”closeModal(‘modalOrderDetail’)”>✕</button>
</div>
<div class=”modal-body”>
<div id=”ord_detail_meta” style=”color:#888;font-size:0.85rem;margin-bottom:1rem;”></div>
<div id=”ord_detail_steps”></div>
</div>
<div class=”modal-footer”>
<button class=”btn btn-primary” onclick=”advanceOrder()”>پیشبرد به مرحله بعد ✓</button>
<button class=”btn btn-danger” onclick=”cancelOrder()”>لغو سفارش</button>
<button class=”btn” onclick=”closeModal(‘modalOrderDetail’)”>بستن</button>
</div>
</div>
</div>
<!– مودال کاربر –>
<div id=”modalUser” class=”modal”>
<div class=”modal-box”>
<div class=”modal-header”>
<h2 id=”userModalTitle”>کاربر جدید</h2>
<button class=”close-btn” onclick=”closeModal(‘modalUser’)”>✕</button>
</div>
<div class=”modal-body”>
<input type=”hidden” id=”um_id”>
<label>نام کاربری</label>
<input type=”text” id=”um_username” placeholder=”username”>
<label>نام کامل</label>
<input type=”text” id=”um_fullname” placeholder=”نام و نام خانوادگی”>
<label>رمز عبور</label>
<input type=”password” id=”um_password” placeholder=”حداقل 6 کاراکتر”>
<label>نقش</label>
<select id=”um_role”></select>
<label>وضعیت</label>
<select id=”um_status”>
<option value=”active”>فعال</option>
<option value=”inactive”>غیرفعال</option>
</select>
</div>
<div class=”modal-footer”>
<button class=”btn btn-primary” onclick=”UsersManage.saveUser()”>ذخیره</button>
<button class=”btn” onclick=”closeModal(‘modalUser’)”>انصراف</button>
</div>
</div>
</div>
<!– مودال نقش –>
<div id=”modalRole” class=”modal”>
<div class=”modal-box” style=”max-width:600px;”>
<div class=”modal-header”>
<h2 id=”roleModalTitle”>نقش جدید</h2>
<button class=”close-btn” onclick=”closeModal(‘modalRole’)”>✕</button>
</div>
<div class=”modal-body”>
<input type=”hidden” id=”rm_id”>
<label>نام نقش</label>
<input type=”text” id=”rm_name” placeholder=”نام نقش”>
<label>توضیحات</label>
<input type=”text” id=”rm_description” placeholder=”توضیحات اختیاری”>
<div style=”margin-top:1rem;”>
<strong>دسترسیها</strong>
<div id=”rm_permissions” style=”margin-top:0.5rem;”></div>
</div>
</div>
<div class=”modal-footer”>
<button class=”btn btn-primary” onclick=”UsersManage.saveRole()”>ذخیره</button>
<button class=”btn” onclick=”closeModal(‘modalRole’)”>انصراف</button>
</div>
</div>
</div>
<!– ترتیب صحیح: auth.js اول، بقیه بعد –>
<script src=”/js/auth.js”></script>
<script src=”/js/app.js”></script>
<script src=”/js/dashboard.js”></script>
<script src=”/js/inventory.js”></script>
<script src=”/js/sales.js”></script>
<script src=”/js/reports.js”></script>
<script src=”/js/warnings.js”></script>
<script src=”/js/transfer.js”></script>
<script src=”/js/products.js”></script>
<script src=”/js/tickets.js”></script>
<script src=”/js/workflow.js”></script>
<script src=”/js/users_manage.js”></script>
<script>
// نقطه ورود اصلی برنامه – فقط یک بار، با await
document.addEventListener(‘DOMContentLoaded’, async function() {
const ok = await Auth.authGuard();
if (!ok) return;
if (typeof loadInitialData === ‘function’) await loadInitialData();
if (typeof initEventListeners === ‘function’) initEventListeners();
if (typeof showPage === ‘function’) showPage(‘dashboard’);
});
</script>
</body>
</html>