KIM237/batistock-pro
0
1// Mock Data Store2const Store = {3 currentUser: JSON.parse(localStorage.getItem('currentUser')) || null,4 5 users: [6 { id: 1, name: 'Admin System', email: 'admin@baticonfort.com', role: 'admin', avatar: 'AS' },7 { id: 2, name: 'Marie Dubois', email: 'marie@baticonfort.com', role: 'gestionnaire', avatar: 'MD' },8 { id: 3, name: 'Pierre Martin', email: 'pierre@baticonfort.com', role: 'production', avatar: 'PM' },9 { id: 4, name: 'Sophie Bernard', email: 'sophie@baticonfort.com', role: 'comptable', avatar: 'SB' }10 ],11 12 products: [13 { id: 1, name: 'Porte PVC Standard', type: 'porte', category: 'pvc', stock: 45, minStock: 10, price: 250000 },14 { id: 2, name: 'Fenêtre Aluminium 120x100', type: 'fenetre', category: 'aluminium', stock: 12, minStock: 15, price: 180000 },15 { id: 3, name: 'Mur-rideau Premium', type: 'mur-rideau', category: 'aluminium', stock: 8, minStock: 5, price: 450000 },16 { id: 4, name: 'Accessoire Joint PVC', type: 'accessoire', category: 'pvc', stock: 150, minStock: 50, price: 5000 },17 { id: 5, name: 'Revêtement Alco-bon', type: 'revetement', category: 'aluminium', stock: 30, minStock: 20, price: 75000 }18 ],19 20 rawMaterials: [21 { id: 1, name: 'Profilé PVC Brut', type: 'matiere', category: 'pvc', stock: 500, unit: 'mètres' },22 { id: 2, name: 'Barre Aluminium 6060', type: 'matiere', category: 'aluminium', stock: 320, unit: 'mètres' }23 ],24 25 quotes: [26 { id: 'DEV-2024-001', client: 'Client A', date: '2024-01-15', total: 850000, status: 'paid', items: [{product: 'Porte PVC Standard', qty: 2}] },27 { id: 'DEV-2024-002', client: 'Client B', date: '2024-01-16', total: 1200000, status: 'validated', items: [] },28 { id: 'DEV-2024-003', client: 'Client C', date: '2024-01-16', total: 540000, status: 'pending', items: [] }29 ],30 31 movements: [32 { id: 1, type: 'entry', product: 'Profilé PVC Brut', quantity: 100, date: '2024-01-15', user: 'Marie Dubois' },33 { id: 2, type: 'exit', product: 'Porte PVC Standard', quantity: 2, date: '2024-01-16', user: 'Marie Dubois', quote: 'DEV-2024-001' },34 { id: 3, type: 'entry', product: 'Fenêtre Aluminium 120x100', quantity: 20, date: '2024-01-16', user: 'Marie Dubois' }35 ],36 37 init() {38 if (!localStorage.getItem('initialized')) {39 localStorage.setItem('products', JSON.stringify(this.products));40 localStorage.setItem('rawMaterials', JSON.stringify(this.rawMaterials));41 localStorage.setItem('quotes', JSON.stringify(this.quotes));42 localStorage.setItem('movements', JSON.stringify(this.movements));43 localStorage.setItem('initialized', 'true');44 }45 },46 47 getProducts() {48 return JSON.parse(localStorage.getItem('products')) || this.products;49 },50 51 getQuotes() {52 return JSON.parse(localStorage.getItem('quotes')) || this.quotes;53 },54 55 getMovements() {56 return JSON.parse(localStorage.getItem('movements')) || this.movements;57 }58};59 60Store.init();61 62// Auth Handler63document.addEventListener('DOMContentLoaded', () => {64 const loginForm = document.getElementById('loginForm');65 66 if (loginForm) {67 loginForm.addEventListener('submit', (e) => {68 e.preventDefault();69 const role = document.getElementById('role').value;70 const username = document.getElementById('username').value;71 72 // Mock authentication73 const user = Store.users.find(u => u.role === role) || Store.users[0];74 user.name = username || user.name;75 76 localStorage.setItem('currentUser', JSON.stringify(user));77 window.location.href = 'dashboard.html';78 });79 }80 81 // Check auth on protected pages82 const protectedPages = ['dashboard', 'products', 'quotes', 'stock', 'users', 'reports'];83 const currentPage = window.location.pathname.split('/').pop().replace('.html', '');84 85 if (protectedPages.includes(currentPage) && !Store.currentUser) {86 window.location.href = 'index.html';87 }88 89 // Update UI with user info90 if (Store.currentUser) {91 document.querySelectorAll('.user-name').forEach(el => el.textContent = Store.currentUser.name);92 document.querySelectorAll('.user-role').forEach(el => el.textContent = getRoleLabel(Store.currentUser.role));93 document.querySelectorAll('.user-avatar').forEach(el => el.textContent = Store.currentUser.avatar);94 95 // Role-based UI adjustments96 adjustUIBasedOnRole(Store.currentUser.role);97 }98});99 100function getRoleLabel(role) {101 const roles = {102 'admin': 'Administrateur',103 'gestionnaire': 'Gestionnaire de Stock',104 'production': 'Responsable Production',105 'comptable': 'Service Comptable'106 };107 return roles[role] || role;108}109 110function adjustUIBasedOnRole(role) {111 // Hide/show menu items based on role112 const menuItems = document.querySelectorAll('[data-role]');113 menuItems.forEach(item => {114 const allowedRoles = item.getAttribute('data-role').split(',');115 if (!allowedRoles.includes(role) && !allowedRoles.includes('all')) {116 item.style.display = 'none';117 }118 });119}120 121function logout() {122 localStorage.removeItem('currentUser');123 window.location.href = 'index.html';124}125 126// Utility functions127function formatCurrency(amount) {128 return new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'XOF' }).format(amount);129}130 131function formatDate(dateString) {132 return new Date(dateString).toLocaleDateString('fr-FR');133}134 135function getStatusBadge(status) {136 const statuses = {137 'pending': '<span class="status-badge status-pending"><i data-feather="clock" class="w-3 h-3 inline mr-1"></i>En attente</span>',138 'validated': '<span class="status-badge status-validated"><i data-feather="check" class="w-3 h-3 inline mr-1"></i>Validé</span>',139 'paid': '<span class="status-badge status-paid"><i data-feather="dollar-sign" class="w-3 h-3 inline mr-1"></i>Payé</span>',140 'delivered': '<span class="status-badge status-delivered">Livré</span>'141 };142 return statuses[status] || status;143}144 145// Search and Filter146function filterTable(inputId, tableId) {147 const input = document.getElementById(inputId);148 const filter = input.value.toLowerCase();149 const table = document.getElementById(tableId);150 const tr = table.getElementsByTagName('tr');151 152 for (let i = 1; i < tr.length; i++) {153 const td = tr[i].getElementsByTagName('td');154 let found = false;155 for (let j = 0; j < td.length; j++) {156 if (td[j] && td[j].textContent.toLowerCase().indexOf(filter) > -1) {157 found = true;158 break;159 }160 }161 tr[i].style.display = found ? '' : 'none';162 }163}164 165// Export for components166window.Store = Store;167window.formatCurrency = formatCurrency;168window.formatDate = formatDate;169window.getStatusBadge = getStatusBadge;170window.logout = logout;