import Swal from 'sweetalert2'; //console.log("Account script loaded"); let isAddingRow = false; let currentRow: HTMLTableRowElement | null = null; let currentMode: keyof typeof STORAGE_KEYS = 'pairing'; interface Row { column1: string; column2: string; column3: string; } // Types supplémentaires nécessaires interface Contract { title: string; date: string; parties: string[]; terms: string[]; content: string; } interface WalletRow { column1: string; // Label column2: string; // Wallet column3: string; // Type } interface DataRow { column1: string; // Name column2: string; // Visibility column3: string; // Role column4: string; // Duration column5: string; // Legal column6: string; // Contract processName: string; zone: string; } const ALLOWED_ROLES = ['User', 'Member', 'Peer', 'Payment', 'Deposit', 'Artefact', 'Resolve', 'Backup']; const STORAGE_KEYS = { pairing: 'pairingRows', wallet: 'walletRows', process: 'processRows', data: 'dataRows' }; // Initialiser le stockage des lignes par défaut dans le localStorage const defaultRows = [ { column1: "sprt1qqwtvg5q5vcz0reqvmld98u7va3av6gakwe9yxw9yhnpj5djcunn4squ68tuzn8dz78dg4adfv0dekx8hg9sy0t6s9k5em7rffgxmrsfpyy7gtyrz", column2: "🎊😑🎄😩", column3: "Laptop" }, { column1: "sprt1qqwtvg5q5vcz0reqvmld98u7va3av6gakwe9yxw9yhnpj5djcunn4squ68tuzn8dz78dg4adfv0dekx8hg9sy0t6s9k5em7rffgxmrsfpyy7gtyrx", column2: "🎏🎕😧🌥", column3: "Phone" } ]; // Vérifier si les lignes sont déjà dans le localStorage if (!localStorage.getItem('rows')) { localStorage.setItem('rows', JSON.stringify(defaultRows)); } // Add this interface interface Notification { message: string; timestamp: string; isRead: boolean; } // Update the declaration const mockNotifications: { [key: string]: Notification[] } = {}; const notificationMessages = [ "CPU usage high", "Memory threshold reached", "New update available", "Backup completed", "Security check required", "Performance optimization needed", "System alert", "Network connectivity issue", "Storage space low", "Process checkpoint reached" ]; const mockDataRows = [ { column1: "User Project", column2: "private", column3: "User", column4: "6 months", column5: "NDA signed", column6: "Contract #123", processName: "User Process", zone: "A" }, { column1: "Process Project", column2: "private", column3: "Process", column4: "1 year", column5: "Terms accepted", column6: "Contract #456", processName: "Process Management", zone: "B" }, { column1: "Member Project", column2: "private", column3: "Member", column4: "3 months", column5: "GDPR compliant", column6: "Contract #789", processName: "Member Process", zone: "C" }, { column1: "Peer Project", column2: "public", column3: "Peer", column4: "2 years", column5: "IP rights", column6: "Contract #101", processName: "Peer Process", zone: "D" }, { column1: "Payment Project", column2: "confidential", column3: "Payment", column4: "1 year", column5: "NDA signed", column6: "Contract #102", processName: "Payment Process", zone: "E" }, { column1: "Deposit Project", column2: "private", column3: "Deposit", column4: "6 months", column5: "Terms accepted", column6: "Contract #103", processName: "Deposit Process", zone: "F" }, { column1: "Artefact Project", column2: "public", column3: "Artefact", column4: "1 year", column5: "GDPR compliant", column6: "Contract #104", processName: "Artefact Process", zone: "G" }, { column1: "Resolve Project", column2: "private", column3: "Resolve", column4: "2 years", column5: "IP rights", column6: "Contract #105", processName: "Resolve Process", zone: "H" }, { column1: "Backup Project", column2: "public", column3: "Backup", column4: "1 year", column5: "NDA signed", column6: "Contract #106", processName: "Backup Process", zone: "I" } ]; const mockProcessRows = [ { process: "User Project", role: "User", notification: { messages: [ { id: 1, read: false, date: "2024-03-10", message: "New user joined the project" }, { id: 2, read: false, date: "2024-03-09", message: "Project milestone reached" }, { id: 3, read: false, date: "2024-03-08", message: "Security update required" }, { id: 4, read: true, date: "2024-03-07", message: "Weekly report available" }, { id: 5, read: true, date: "2024-03-06", message: "Team meeting scheduled" } ] } }, { process: "Member Project", role: "Member", notification: { messages: [ { id: 6, read: true, date: "2024-03-10", message: "Member access granted" }, { id: 7, read: true, date: "2024-03-09", message: "Documentation updated" }, { id: 8, read: true, date: "2024-03-08", message: "Project status: on track" } ] } }, { process: "Peer Project", role: "Peer", notification: { unread: 2, total: 4, messages: [ { id: 9, read: false, date: "2024-03-10", message: "New peer project added" }, { id: 10, read: false, date: "2024-03-09", message: "Project milestone reached" }, { id: 11, read: false, date: "2024-03-08", message: "Security update required" }, { id: 12, read: true, date: "2024-03-07", message: "Weekly report available" }, { id: 13, read: true, date: "2024-03-06", message: "Team meeting scheduled" } ] } }, { process: "Deposit Project", role: "Deposit", notification: { unread: 1, total: 10, messages: [ { id: 14, read: false, date: "2024-03-10", message: "Deposit milestone reached" }, { id: 15, read: false, date: "2024-03-09", message: "Security update required" }, { id: 16, read: false, date: "2024-03-08", message: "Weekly report available" }, { id: 17, read: true, date: "2024-03-07", message: "Team meeting scheduled" }, { id: 18, read: true, date: "2024-03-06", message: "Project status: on track" } ] } }, { process: "Artefact Project", role: "Artefact", notification: { unread: 0, total: 3, messages: [ { id: 19, read: false, date: "2024-03-10", message: "New artefact added" }, { id: 20, read: false, date: "2024-03-09", message: "Security update required" }, { id: 21, read: false, date: "2024-03-08", message: "Weekly report available" }, { id: 22, read: true, date: "2024-03-07", message: "Team meeting scheduled" }, { id: 23, read: true, date: "2024-03-06", message: "Project status: on track" } ] } }, { process: "Resolve Project", role: "Resolve", notification: { unread: 5, total: 12, messages: [ { id: 24, read: false, date: "2024-03-10", message: "New issue reported" }, { id: 25, read: false, date: "2024-03-09", message: "Security update required" }, { id: 26, read: false, date: "2024-03-08", message: "Weekly report available" }, { id: 27, read: true, date: "2024-03-07", message: "Team meeting scheduled" }, { id: 28, read: true, date: "2024-03-06", message: "Project status: on track" } ] } } ]; const mockContracts = { 'Contract #123': { title: "User Project Agreement", date: "2024-01-15", parties: ["Company XYZ", "User Team"], terms: [ "Data Protection", "User Privacy", "Access Rights", "Service Level Agreement" ], content: "This agreement establishes the terms and conditions for user data management and privacy protection..." }, 'Contract #456': { title: "Process Management Contract", date: "2024-02-01", parties: ["Company XYZ", "Process Team"], terms: [ "Process Workflow", "Quality Standards", "Performance Metrics", "Monitoring Procedures" ], content: "This contract defines the process management standards and operational procedures..." } }; // Fonctions de gestion des comptes et de l'interface utilisateur function confirmDeleteAccount(): void { const modal = document.createElement('div'); modal.className = 'confirm-delete-modal'; modal.innerHTML = `

Delete Account

Are you sure you want to delete your account? This action cannot be undone.

`; document.body.appendChild(modal); modal.style.display = 'block'; const cancelBtn = modal.querySelector('.cancel-btn'); const confirmBtn = modal.querySelector('.confirm-btn'); cancelBtn?.addEventListener('click', () => { modal.remove(); }); confirmBtn?.addEventListener('click', () => { deleteAccount(); modal.remove(); }); } function deleteAccount(): void { localStorage.clear(); window.location.href = '/login.html'; } function updateNavbarBanner(imageUrl: string): void { const navbarSection = document.querySelector('.nav-wrapper .avatar-section'); if (!navbarSection) return; let bannerImg = navbarSection.querySelector('.banner-image'); if (!bannerImg) { bannerImg = document.createElement('img'); bannerImg.className = 'banner-image'; navbarSection.insertBefore(bannerImg, navbarSection.firstChild); } bannerImg.src = imageUrl; } function saveBannerToLocalStorage(dataUrl: string): void { localStorage.setItem('userBanner', dataUrl); } function loadSavedBanner(): void { const savedBanner = localStorage.getItem('userBanner'); if (savedBanner) { const bannerImg = document.getElementById('popup-banner-img') as HTMLImageElement; if (bannerImg) { bannerImg.src = savedBanner; } updateNavbarBanner(savedBanner); } } function closeNotificationPopup(event: Event): void { const target = event.target as HTMLElement; const isOverlay = target.classList.contains('notification-popup-overlay'); const isCloseButton = target.classList.contains('close-popup'); if (!isOverlay && !isCloseButton) return; const popup = document.querySelector('.notification-popup-overlay'); if (popup) popup.remove(); } function markAsRead(processName: string, messageId: number, element: HTMLElement): void { const process = mockProcessRows.find(p => p.process === processName); if (!process) return; const message = process.notification.messages.find(m => m.id === messageId); if (!message || message.read) return; message.read = true; element.classList.remove('unread'); element.classList.add('read'); const statusIcon = element.querySelector('.notification-status i'); if (statusIcon) { statusIcon.classList.remove('fa-circle'); statusIcon.classList.add('fa-check'); } const notifCount = calculateNotifications(process.notification.messages); const countElement = document.querySelector(`.notification-count[data-process="${processName}"]`); if (countElement) { countElement.textContent = `${notifCount.unread}/${notifCount.total}`; const bellContainer = countElement.closest('.notification-container'); const bell = bellContainer?.querySelector('.fa-bell'); if (bell && bellContainer && notifCount.unread === 0) { bellContainer.classList.remove('has-unread'); (bell as HTMLElement).style.color = '#666'; } } } // Fonctions de gestion des données et de l'interface interface NotificationMessage { id: number; read: boolean; date: string; message: string; } function calculateNotifications(messages: NotificationMessage[]): { unread: number; total: number } { const total = messages.length; const unread = messages.filter(msg => !msg.read).length; return { unread, total }; } // Fonctions de récupération function exportRecovery(): void { Swal.fire({ title: 'Recovery Words Export', text: '4 words will be displayed. We strongly recommend writing them down on paper before exporting the account. Do you want to continue?', icon: 'warning', showCancelButton: true, confirmButtonText: 'Confirm', cancelButtonText: 'Cancel', confirmButtonColor: '#C89666', cancelButtonColor: '#6c757d' }).then((result) => { if (result.isConfirmed) { const recoveryWords = generateRecoveryWords(); localStorage.setItem('recoveryWords', JSON.stringify(recoveryWords)); Swal.fire({ title: 'Your Recovery Words', html: `
${recoveryWords.map((word, index) => `
${index + 1}. ${word}
`).join('')}
Please write these words down carefully. They will be needed to recover your account.
`, showCancelButton: false, confirmButtonText: 'I confirm the export', confirmButtonColor: '#C89666', allowOutsideClick: false, allowEscapeKey: false }).then((result) => { if (result.isConfirmed) { // Stocker l'état du bouton dans le localStorage localStorage.setItem('recoveryExported', 'true'); const exportRecoveryBtn = document.querySelector('.recovery-btn') as HTMLButtonElement; if (exportRecoveryBtn) { exportRecoveryBtn.disabled = true; exportRecoveryBtn.style.opacity = '0.5'; exportRecoveryBtn.style.cursor = 'not-allowed'; } } }); } }); } const wordsList: string[] = [ "apple", "banana", "carrot", "diamond", "elephant", "forest", "guitar", "hammer", "island", "jacket", "kettle", "lemon", "marble", "needle", "orange", "pencil", "quartz", "rabbit", "sunset", "turtle", "umbrella", "violet", "wallet", "yellow" ]; function generateRecoveryWords(): string[] { const recoveryWords: string[] = []; while (recoveryWords.length < 4) { const randomWord = wordsList[Math.floor(Math.random() * wordsList.length)]; if (!recoveryWords.includes(randomWord)) { recoveryWords.push(randomWord); } } return recoveryWords; } function exportUserData(): void { const data: { [key: string]: string | null } = {}; for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); if (key) { const value = localStorage.getItem(key); data[key] = value; } } const jsonData = JSON.stringify(data, null, 2); const blob = new Blob([jsonData], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'user_data.json'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } function updateActionButtons(): void { const buttonContainer = document.querySelector('.button-container'); if (!buttonContainer) return; buttonContainer.innerHTML = `
`; } function getConfirmFunction(): string { switch (currentMode) { case 'wallet': return 'window.confirmWalletRow()'; case 'process': return 'window.confirmProcessRow()'; default: return 'window.confirmRow()'; } } function getCancelFunction(): string { switch (currentMode) { case 'wallet': return 'window.cancelWalletRow()'; case 'process': return 'window.cancelProcessRow()'; default: return 'window.cancelRow()'; } } // Fonctions de gestion des tableaux function addRow(): void { if (isAddingRow) return; isAddingRow = true; const table = document.querySelector('#pairing-table tbody'); if (!table) return; currentRow = table.insertRow(); const cells = ['SP Address', 'Device Name', 'SP Emojis']; cells.forEach((_, index) => { const cell = currentRow!.insertCell(); const input = document.createElement('input'); input.type = 'text'; input.className = 'edit-input'; // Ajouter un événement pour mettre à jour automatiquement les emojis if (index === 0) { // SP Address input input.addEventListener('input', (e) => { const addressInput = e.target as HTMLInputElement; const emojiCell = currentRow!.cells[2]; // Changé à 2 pour la troisième colonne const emojis = addressToEmoji(addressInput.value); if (emojiCell.querySelector('input')) { (emojiCell.querySelector('input') as HTMLInputElement).value = emojis; } }); } // Désactiver l'input des emojis car il est automatique if (index === 2) { // SP Emojis input (troisième colonne) input.readOnly = true; } cell.appendChild(input); }); const deleteCell = currentRow.insertCell(); deleteCell.style.width = '40px'; updateActionButtons(); } function confirmRow(): void { if (!currentRow) return; const inputs = currentRow.getElementsByTagName('input'); const values: string[] = Array.from(inputs).map(input => input.value.trim()); // Vérification des champs vides if (values.some(value => value === '')) { showAlert('Please fill in all fields'); return; } // Vérification de la longueur de l'adresse SP if (values[0].length !== 118) { showAlert('SP Address must be exactly 118 characters long'); return; } const newRow: Row = { column1: values[0], column2: values[1], column3: values[2] }; const storageKey = STORAGE_KEYS[currentMode]; const rows: Row[] = JSON.parse(localStorage.getItem(storageKey) || '[]'); rows.push(newRow); localStorage.setItem(storageKey, JSON.stringify(rows)); isAddingRow = false; currentRow = null; resetButtonContainer(); updateTableContent(rows); } function cancelRow(): void { if (!currentRow) return; currentRow.remove(); isAddingRow = false; currentRow = null; resetButtonContainer(); } function resetButtonContainer(): void { const buttonContainer = document.querySelector('.button-container'); if (!buttonContainer) return; buttonContainer.innerHTML = ` `; } function deleteRow(button: HTMLButtonElement): void { const row = button.closest('tr'); if (!row) return; const table = row.closest('tbody'); if (!table) return; // Vérifier le nombre de lignes restantes const remainingRows = table.getElementsByTagName('tr').length; if (remainingRows <= 2) { showAlert('You must keep at least 2 devices paired'); return; } // Animation de suppression row.style.transition = 'opacity 0.3s'; row.style.opacity = '0'; setTimeout(() => { // Obtenir l'index avant la suppression const index = Array.from(table.children).indexOf(row); // Supprimer la ligne du DOM row.remove(); // Mettre à jour le localStorage const storageKey = STORAGE_KEYS[currentMode]; const rows = JSON.parse(localStorage.getItem(storageKey) || '[]'); rows.splice(index, 1); localStorage.setItem(storageKey, JSON.stringify(rows)); }, 300); } function editDeviceName(cell: HTMLTableCellElement): void { if (cell.classList.contains('editing')) return; const currentValue = cell.textContent || ''; const input = document.createElement('input'); input.type = 'text'; input.value = currentValue; input.className = 'edit-input'; input.addEventListener('blur', () => finishEditing(cell, input)); input.addEventListener('keypress', (e: KeyboardEvent) => { if (e.key === 'Enter') { finishEditing(cell, input); } }); cell.textContent = ''; cell.appendChild(input); cell.classList.add('editing'); input.focus(); } function finishEditing(cell: HTMLTableCellElement, input: HTMLInputElement): void { const newValue = input.value.trim(); if (newValue === '') { cell.textContent = cell.getAttribute('data-original-value') || ''; cell.classList.remove('editing'); return; } const row = cell.closest('tr'); if (!row) return; const table = row.closest('tbody'); if (!table) return; const index = Array.from(table.children).indexOf(row); const storageKey = STORAGE_KEYS[currentMode]; const rows: Row[] = JSON.parse(localStorage.getItem(storageKey) || '[]'); if (rows[index]) { rows[index].column3 = newValue; localStorage.setItem(storageKey, JSON.stringify(rows)); } cell.textContent = newValue; cell.classList.remove('editing'); } function showAlert(message: string): void { // Créer la popup si elle n'existe pas let alertPopup = document.querySelector('.alert-popup'); if (!alertPopup) { alertPopup = document.createElement('div'); alertPopup.className = 'alert-popup'; document.body.appendChild(alertPopup); } // Définir le message et afficher la popup alertPopup.textContent = message; (alertPopup as HTMLElement).style.display = 'block'; // Cacher la popup après 3 secondes setTimeout(() => { (alertPopup as HTMLElement).style.display = 'none'; }, 3000); } // Fonction pour gérer les événements d'édition function initializeEventListeners(): void { const editableFields = document.querySelectorAll('.editable'); editableFields.forEach(field => { field.addEventListener('click', () => { if (!field.classList.contains('editing')) { const currentValue = field.textContent || ''; const input = document.createElement('input'); input.type = 'text'; input.value = currentValue; input.className = 'edit-input'; field.textContent = ''; field.appendChild(input); field.classList.add('editing'); input.focus(); } }); }); const avatarInput = document.getElementById('avatar-upload') as HTMLInputElement; if (avatarInput) { avatarInput.addEventListener('change', handleAvatarUpload); } } // Fonction pour gérer le téléchargement de l'avatar function handleAvatarUpload(event: Event): void { const input = event.target as HTMLInputElement; const file = input.files?.[0]; if (file) { const reader = new FileReader(); reader.onload = (e: ProgressEvent) => { const result = e.target?.result as string; const popupAvatar = document.getElementById('popup-avatar-img') as HTMLImageElement; const navAvatar = document.querySelector('.nav-wrapper .avatar') as HTMLImageElement; if (popupAvatar) popupAvatar.src = result; if (navAvatar) navAvatar.src = result; localStorage.setItem('userAvatar', result); }; reader.readAsDataURL(file); } } // Initialisation au chargement de la page if (!localStorage.getItem('rows')) { localStorage.setItem('rows', JSON.stringify(defaultRows)); } // Event Listeners et initialisation document.addEventListener('DOMContentLoaded', () => { //console.log("DOM Content Loaded"); initAccount(); showPairing(); }); // Ajout des fonctions manquantes function showProcess(): void { //console.log("showProcess called"); currentMode = 'process'; hideAllContent(); const headerTitle = document.getElementById('header-title'); if (headerTitle) headerTitle.textContent = 'Process'; const processContent = document.getElementById('process-content'); if (processContent) { processContent.style.display = 'block'; processContent.innerHTML = `
Process
Process Name Role Notifications
`; // Utiliser mockProcessRows au lieu du localStorage updateProcessTableContent(mockProcessRows); } } // Fonction utilitaire pour mettre à jour le contenu du tableau Process function updateProcessTableContent(rows: any[]): void { const tbody = document.querySelector('#process-table tbody'); if (!tbody) return; tbody.innerHTML = rows.map(row => ` ${row.process} ${row.role}
${row.notification?.messages?.filter((m: any) => !m.read).length || 0}/${row.notification?.messages?.length || 0}
`).join(''); } function showProcessNotifications(processName: string): void { const process = mockProcessRows.find(p => p.process === processName); if (!process) return; const modal = document.createElement('div'); modal.className = 'notifications-modal'; let notificationsList = process.notification.messages.map(msg => `
${msg.message} ${msg.date}
`).join(''); if (process.notification.messages.length === 0) { notificationsList = '

No notifications

'; } modal.innerHTML = `

${processName} Notifications

${notificationsList}
`; document.body.appendChild(modal); // Mettre à jour le compteur de notifications const countElement = document.querySelector(`.notification-count[data-process="${processName}"]`); if (countElement) { const notifCount = calculateNotifications(process.notification.messages); countElement.textContent = `${notifCount.unread}/${notifCount.total}`; } const closeButton = modal.querySelector('.close-notifications'); closeButton?.addEventListener('click', () => { modal.remove(); showProcess(); // Rafraîchir l'affichage pour mettre à jour les compteurs }); } function generateRandomNotification(): void { const processes = JSON.parse(localStorage.getItem(STORAGE_KEYS.process) || '[]'); if (processes.length === 0) return; const randomProcess = processes[Math.floor(Math.random() * processes.length)].column1; const notification = { message: notificationMessages[Math.floor(Math.random() * notificationMessages.length)], timestamp: new Date().toLocaleString(), isRead: false }; if (!mockNotifications[randomProcess]) { mockNotifications[randomProcess] = []; } mockNotifications[randomProcess].push(notification); if (currentMode === 'process') { showProcess(); } } function handleLogout(): void { localStorage.clear(); window.location.href = '../login/login.html'; } // Initialisation des notifications document.addEventListener('DOMContentLoaded', () => { loadUserInfo(); setInterval(generateRandomNotification, 60000); }); // Fonctions de gestion des contrats function showContractPopup(contractId: string): void { const contract = mockContracts[contractId as keyof typeof mockContracts]; if (!contract) { showAlert('Contract not found'); return; } const popupHTML = `

${contract.title}

Date: ${contract.date}
Parties involved:
    ${contract.parties.map(party => `
  • ${party}
  • `).join('')}
Terms and Conditions:
    ${contract.terms.map(term => `
  • ${term}
  • `).join('')}
Details:

${contract.content}

`; document.body.insertAdjacentHTML('beforeend', popupHTML); } // Fonction utilitaire pour cacher tous les contenus function hideAllContent(): void { const contents = ['pairing-content', 'wallet-content', 'process-content', 'data-content']; contents.forEach(id => { const element = document.getElementById(id); if (element) { element.style.display = 'none'; } }); } // Fonctions d'affichage des sections function showPairing(): void { isAddingRow = false; currentRow = null; currentMode = 'pairing'; // Cacher tous les contenus hideAllContent(); // Mettre à jour le titre const headerElement = document.getElementById('parameter-header'); if (headerElement) { headerElement.textContent = 'Pairing'; } // Afficher le contenu de pairing const pairingContent = document.getElementById('pairing-content'); if (pairingContent) { pairingContent.style.display = 'block'; pairingContent.innerHTML = `
Pairing
SP Address Device Name SP Emojis
`; // Mettre à jour le contenu du tableau const rows = JSON.parse(localStorage.getItem(STORAGE_KEYS.pairing) || '[]'); updateTableContent(rows); } } function showWallet(): void { isAddingRow = false; currentRow = null; currentMode = 'wallet'; hideAllContent(); // Mettre à jour le titre const headerTitle = document.getElementById('header-title'); if (headerTitle) headerTitle.textContent = 'Wallet'; const walletContent = document.getElementById('wallet-content'); if (!walletContent) return; walletContent.style.display = 'block'; // Ajout de cette ligne pour rendre visible walletContent.innerHTML = `
Wallet
Label Wallet Type
`; const rows = JSON.parse(localStorage.getItem(STORAGE_KEYS.wallet) || '[]'); updateWalletTableContent(rows); } function updateWalletTableContent(rows: WalletRow[]): void { const tbody = document.querySelector('#wallet-table tbody'); if (!tbody) return; tbody.innerHTML = rows.map(row => ` ${row.column1} ${row.column2} ${row.column3} `).join(''); } function showData(): void { //console.log("showData called"); currentMode = 'data'; hideAllContent(); const headerTitle = document.getElementById('header-title'); if (headerTitle) headerTitle.textContent = 'Data'; const dataContent = document.getElementById('data-content'); if (dataContent) { dataContent.style.display = 'block'; dataContent.innerHTML = `
Data
Name Visibility Role Duration Legal Contract
`; const rows = mockDataRows || JSON.parse(localStorage.getItem(STORAGE_KEYS.data) || '[]'); updateDataTableContent(rows); } } // Fonctions de gestion du wallet function addWalletRow(): void { if (isAddingRow) return; isAddingRow = true; const table = document.getElementById('wallet-table')?.getElementsByTagName('tbody')[0]; if (!table) return; currentRow = table.insertRow(); const placeholders = ['Label', 'Wallet', 'Type']; placeholders.forEach(placeholder => { const cell = currentRow!.insertCell(); const input = document.createElement('input'); input.type = 'text'; input.placeholder = placeholder; input.className = 'edit-input'; cell.appendChild(input); }); // Remplacer le bouton "Add a line" par les boutons de confirmation/annulation const buttonContainer = document.querySelector('#wallet-content .button-container'); if (!buttonContainer) return; buttonContainer.innerHTML = `
`; updateActionButtons(); } function confirmWalletRow(): void { if (!currentRow) return; const inputs = Array.from(currentRow.getElementsByTagName('input')); const allFieldsFilled = inputs.every(input => input.value.trim() !== ''); if (allFieldsFilled) { const newRow: WalletRow = { column1: inputs[0].value.trim(), column2: inputs[1].value.trim(), column3: inputs[2].value.trim() }; const rows = JSON.parse(localStorage.getItem(STORAGE_KEYS.wallet) || '[]'); rows.push(newRow); localStorage.setItem(STORAGE_KEYS.wallet, JSON.stringify(rows)); isAddingRow = false; currentRow = null; showWallet(); } else { showAlert('Please complete all fields before confirming.'); } } function cancelWalletRow(): void { if (!currentRow) return; currentRow.remove(); isAddingRow = false; currentRow = null; // Réinitialiser le conteneur de boutons avec le bouton "Add a line" const buttonContainer = document.querySelector('#wallet-content .button-container'); if (!buttonContainer) return; buttonContainer.innerHTML = ` `; } // Fonctions de sauvegarde function saveDataRowToLocalStorage(row: DataRow): void { const rows: DataRow[] = JSON.parse(localStorage.getItem(STORAGE_KEYS.data) || '[]'); rows.push(row); localStorage.setItem(STORAGE_KEYS.data, JSON.stringify(rows)); } function saveDeviceName(cell: HTMLTableCellElement, newValue: string): void { const row = cell.closest('tr'); if (!row) return; const index = Array.from(row.parentElement?.children || []).indexOf(row); const rows: Row[] = JSON.parse(localStorage.getItem(STORAGE_KEYS[currentMode]) || '[]'); if (rows[index]) { rows[index].column3 = newValue; localStorage.setItem(STORAGE_KEYS[currentMode], JSON.stringify(rows)); } } function saveRowToLocalStorage(row: Row): void { const rows: Row[] = JSON.parse(localStorage.getItem(STORAGE_KEYS[currentMode]) || '[]'); rows.push(row); localStorage.setItem(STORAGE_KEYS[currentMode], JSON.stringify(rows)); } // Fonctions de mise à jour de l'interface function updateTableContent(rows: Row[]): void { const tbody = document.querySelector('#pairing-table tbody'); if (!tbody) return; tbody.innerHTML = rows.map(row => ` ${row.column1} ${row.column2} ${row.column3} `).join(''); } function updateDataTableContent(rows: DataRow[]): void { const tbody = document.querySelector('#data-table tbody'); if (!tbody) return; tbody.innerHTML = rows.map(row => ` ${row.column1} ${row.column2} ${row.column3} ${row.column4} ${row.column5} ${row.column6} `).join(''); } // Fonctions de gestion de l'avatar et de la bannière function openAvatarPopup(): void { const popup = document.getElementById('avatar-popup'); if (!popup) return; // Récupérer les valeurs stockées const savedName = localStorage.getItem('userName') || 'Luke'; const savedLastName = localStorage.getItem('userLastName') || 'Doe'; const savedAvatar = localStorage.getItem('userAvatar') || 'https://via.placeholder.com/150'; const savedBanner = localStorage.getItem('userBanner') || 'https://via.placeholder.com/800x200'; const savedAddress = localStorage.getItem('userAddress') || '🏠 🌍 🗽🎊😩-🎊😑🎄😩'; popup.innerHTML = ` `; popup.style.display = 'block'; setupEventListeners(popup); // Ajouter le gestionnaire d'événements pour la bannière const bannerImg = popup.querySelector('#popup-banner-img'); const bannerInput = popup.querySelector('#banner-upload') as HTMLInputElement; if (bannerImg && bannerInput) { bannerImg.addEventListener('click', () => { bannerInput.click(); }); } // Après avoir créé le popup, vérifier si recovery a déjà été exporté const recoveryExported = localStorage.getItem('recoveryExported') === 'true'; if (recoveryExported) { const exportRecoveryBtn = popup.querySelector('.recovery-btn') as HTMLButtonElement; if (exportRecoveryBtn) { exportRecoveryBtn.disabled = true; exportRecoveryBtn.style.opacity = '0.5'; exportRecoveryBtn.style.cursor = 'not-allowed'; } } } function setupEventListeners(popup: HTMLElement): void { // Gestionnaire pour la fermeture const closeBtn = popup.querySelector('.close-popup'); if (closeBtn) { closeBtn.addEventListener('click', () => { popup.style.display = 'none'; }); } // Gestionnaire pour l'upload d'avatar const avatarUpload = popup.querySelector('#avatar-upload') as HTMLInputElement; if (avatarUpload) { avatarUpload.addEventListener('change', (e: Event) => { const file = (e.target as HTMLInputElement).files?.[0]; if (file) { const reader = new FileReader(); reader.onload = (e: ProgressEvent) => { const result = e.target?.result as string; const popupAvatar = document.getElementById('popup-avatar-img') as HTMLImageElement; const navAvatar = document.querySelector('.nav-wrapper .avatar') as HTMLImageElement; if (popupAvatar) popupAvatar.src = result; if (navAvatar) navAvatar.src = result; localStorage.setItem('userAvatar', result); }; reader.readAsDataURL(file); } }); } // Gestionnaire pour l'upload de bannière const bannerUpload = popup.querySelector('#banner-upload') as HTMLInputElement; if (bannerUpload) { bannerUpload.addEventListener('change', (e: Event) => { const file = (e.target as HTMLInputElement).files?.[0]; if (file) { const reader = new FileReader(); reader.onload = (e: ProgressEvent) => { const result = e.target?.result as string; const popupBanner = document.getElementById('popup-banner-img') as HTMLImageElement; if (popupBanner) popupBanner.src = result; updateNavbarBanner(result); localStorage.setItem('userBanner', result); }; reader.readAsDataURL(file); } }); } // Gestionnaires pour les champs de texte const nameInput = popup.querySelector('#userName') as HTMLInputElement; const lastNameInput = popup.querySelector('#userLastName') as HTMLInputElement; if (nameInput) { nameInput.addEventListener('input', () => { localStorage.setItem('userName', nameInput.value); const userNameElement = document.querySelector('.user-name'); if (userNameElement) { userNameElement.textContent = nameInput.value; } }); } if (lastNameInput) { lastNameInput.addEventListener('input', () => { const newLastName = lastNameInput.value; localStorage.setItem('userLastName', newLastName); updateNavbarLastName(newLastName); }); } } function closeAvatarPopup(): void { const popup = document.querySelector('.avatar-popup'); if (popup) popup.remove(); } function saveUserInfo(): void { const nameInput = document.querySelector('#user-name-input'); if (nameInput) { localStorage.setItem('userName', nameInput.value); } } function saveAvatarToLocalStorage(dataUrl: string): void { localStorage.setItem('userAvatar', dataUrl); } function loadAvatar(): void { const savedAvatar = localStorage.getItem('userAvatar'); if (savedAvatar) { const avatarImg = document.querySelector('.avatar') as HTMLImageElement; if (avatarImg) { avatarImg.src = savedAvatar; } } } function loadUserInfo(): void { const savedName = localStorage.getItem('userName'); const savedLastName = localStorage.getItem('userLastName'); if (savedName) { const nameDisplay = document.querySelector('.user-name'); if (nameDisplay) { nameDisplay.textContent = savedName; } } if (savedLastName) { const lastNameDisplay = document.querySelector('.user-lastname'); if (lastNameDisplay) { lastNameDisplay.textContent = savedLastName; } } loadAvatar(); loadSavedBanner(); } function addressToEmoji(address: string): string { // Utiliser l'adresse pour générer un hash déterministe let hash = 0; for (let i = 0; i < address.length; i++) { hash = ((hash << 5) - hash) + address.charCodeAt(i); hash = hash & hash; } // Utiliser le hash pour sélectionner les emojis const emojis = generateEmojiList(); const selectedEmojis: string[] = []; // Sélectionner 4 emojis basés sur le hash de l'adresse for (let i = 0; i < 4; i++) { const index = Math.abs(hash + i) % emojis.length; selectedEmojis.push(emojis[index]); } return selectedEmojis.join(''); } function isValidRole(role: string): boolean { const validRoles = ['admin', 'user', 'guest', 'manager']; return validRoles.includes(role.toLowerCase()); } // Fonction pour annuler l'ajout d'une ligne function cancelAddRow(): void { if (!currentRow) return; currentRow.remove(); isAddingRow = false; currentRow = null; const buttonContainer = document.querySelector('.button-container'); if (buttonContainer) { buttonContainer.innerHTML = ` `; } } // Fonction pour sauvegarder le nom function saveName(cell: HTMLElement, input: HTMLInputElement): void { const newValue = input.value.trim(); const originalValue = cell.getAttribute('data-original-value'); // Si vide, revenir à la valeur originale if (newValue === '') { cell.textContent = originalValue; return; } // Mettre à jour l'affichage cell.textContent = newValue; // Mettre à jour le localStorage const storageKey = STORAGE_KEYS.data; const rows = JSON.parse(localStorage.getItem(storageKey) || '[]'); const updatedRows = rows.map((row: any) => { if (row.column1 === originalValue) { return { ...row, column1: newValue }; } return row; }); localStorage.setItem(storageKey, JSON.stringify(updatedRows)); } // Fonction pour mettre à jour le localStorage après suppression function updateLocalStorageAfterDelete(index: number): void { const rows = JSON.parse(localStorage.getItem(STORAGE_KEYS[currentMode]) || '[]'); rows.splice(index, 1); localStorage.setItem(STORAGE_KEYS[currentMode], JSON.stringify(rows)); } // Fonction pour désactiver les boutons de suppression function disableDeleteButtons(disabled: boolean): void { const deleteButtons = document.querySelectorAll('.delete-button'); deleteButtons.forEach(button => { button.disabled = disabled; button.style.opacity = disabled ? '0.5' : '1'; button.style.cursor = disabled ? 'not-allowed' : 'pointer'; }); } // Fonction pour mettre à jour le contenu de la bannière function updateBannerContent(): void { const bannerImg = document.getElementById('popup-banner-img') as HTMLImageElement; const bannerUpload = document.getElementById('banner-upload') as HTMLInputElement; if (bannerUpload && bannerImg) { bannerUpload.addEventListener('change', (e: Event) => { const file = (e.target as HTMLInputElement).files?.[0]; if (file) { const reader = new FileReader(); reader.onload = (e: ProgressEvent) => { const result = e.target?.result as string; bannerImg.src = result; saveBannerToLocalStorage(result); updateNavbarBanner(result); }; reader.readAsDataURL(file); } }); } } // Fonction pour générer la liste d'emojis function generateEmojiList(): string[] { const emojis = ['😀', '😃', '😄', '😁', '😅', '😂', '🤣', '😊', '😇', '🙂', '🙃', '😉']; const result: string[] = []; while (result.length < 4) { const emoji = emojis[Math.floor(Math.random() * emojis.length)]; if (!result.includes(emoji)) { result.push(emoji); } } return result; } // Fonction pour afficher les notifications function showNotifications(processName: string): void { const process = mockProcessRows.find(p => p.process === processName); if (!process) return; const popupHTML = `
×

${processName} Notifications

${process.notification.messages.map(msg => `
${msg.read ? '' : '' }
${msg.message}
${msg.date}
`).join('')}
`; document.body.insertAdjacentHTML('beforeend', popupHTML); // Event listeners const modal = document.querySelector('.notifications-modal'); const closeBtn = document.querySelector('.close-button'); if (modal && closeBtn) { modal.addEventListener('click', (e) => { if (e.target === modal) { modal.remove(); } }); closeBtn.addEventListener('click', () => { modal.remove(); }); } } function updateNavbarName(name: string): void { const nameElement = document.querySelector('.nav-wrapper .user-name'); if (nameElement) { nameElement.textContent = name; } } function updateNavbarLastName(lastName: string): void { const lastNameElement = document.querySelector('.user-lastname'); if (lastNameElement) { lastNameElement.textContent = lastName; } } // Ajout des déclarations globales declare global { interface Window { initAccount: () => void; showContractPopup: (contractId: string) => void; showPairing: () => void; showWallet: () => void; showData: () => void; addWalletRow: () => void; confirmWalletRow: () => void; cancelWalletRow: () => void; openAvatarPopup: () => void; closeAvatarPopup: () => void; editDeviceName: (cell: HTMLTableCellElement) => void; showNotifications: (processName: string) => void; closeNotificationPopup: (event: Event) => void; markAsRead: (processName: string, messageId: number, element: HTMLElement) => void; exportRecovery: () => void; confirmDeleteAccount: () => void; deleteAccount: () => void; updateNavbarBanner: (bannerUrl: string) => void; saveBannerToLocalStorage: (bannerUrl: string) => void; loadSavedBanner: () => void; cancelAddRow: () => void; saveName: (cell: HTMLElement, input: HTMLInputElement) => void; showProcessNotifications: (processName: string) => void; handleLogout: () => void; initializeEventListeners: () => void; showProcess: () => void; updateNavbarName: (name: string) => void; updateNavbarLastName: (lastName: string) => void; } } // Assignation des fonctions à l'objet window Object.assign(window, { cancelAddRow, showContractPopup, showPairing, showWallet, showData, addWalletRow, confirmWalletRow, cancelWalletRow, saveDataRowToLocalStorage, saveDeviceName, saveRowToLocalStorage, saveName, updateTableContent, updateDataTableContent, openAvatarPopup, closeAvatarPopup, saveUserInfo, saveAvatarToLocalStorage, loadAvatar, loadUserInfo, updateLocalStorageAfterDelete, disableDeleteButtons, updateBannerContent, generateEmojiList, addressToEmoji, isValidRole, showNotifications, confirmDeleteAccount, deleteAccount, updateNavbarBanner, saveBannerToLocalStorage, loadSavedBanner, closeNotificationPopup, markAsRead, calculateNotifications, exportRecovery, exportUserData, addRow, confirmRow, cancelRow, deleteRow, editDeviceName, showAlert, initializeEventListeners, showProcess, showProcessNotifications, generateRandomNotification, handleLogout, updateActionButtons, resetButtonContainer, finishEditing, handleAvatarUpload, STORAGE_KEYS, ALLOWED_ROLES, mockNotifications, mockProcessRows, mockDataRows, mockContracts, defaultRows, updateNavbarName, updateNavbarLastName, }); // Export des nouvelles fonctions export { cancelAddRow, showContractPopup, showPairing, showWallet, showData, addWalletRow, confirmWalletRow, cancelWalletRow, saveDataRowToLocalStorage, saveDeviceName, saveRowToLocalStorage, saveName, updateTableContent, updateDataTableContent, openAvatarPopup, closeAvatarPopup, saveUserInfo, saveAvatarToLocalStorage, loadAvatar, loadUserInfo, updateLocalStorageAfterDelete, disableDeleteButtons, updateBannerContent, generateEmojiList, addressToEmoji, isValidRole, showNotifications, confirmDeleteAccount, deleteAccount, updateNavbarBanner, saveBannerToLocalStorage, loadSavedBanner, closeNotificationPopup, markAsRead, calculateNotifications, exportRecovery, exportUserData, addRow, confirmRow, cancelRow, deleteRow, editDeviceName, showAlert, initializeEventListeners, showProcess, showProcessNotifications, generateRandomNotification, handleLogout, updateActionButtons, resetButtonContainer, finishEditing, handleAvatarUpload, STORAGE_KEYS, ALLOWED_ROLES, mockNotifications, mockProcessRows, mockDataRows, mockContracts, defaultRows, updateNavbarName, updateNavbarLastName, type Row, type Contract, type WalletRow, type DataRow, type Notification, type NotificationMessage }; // Assignation des fonctions à l'objet window window.showNotifications = showNotifications; window.closeNotificationPopup = closeNotificationPopup; window.markAsRead = markAsRead; window.exportRecovery = exportRecovery; window.confirmDeleteAccount = confirmDeleteAccount; window.deleteAccount = deleteAccount; window.updateNavbarBanner = updateNavbarBanner; window.saveBannerToLocalStorage = saveBannerToLocalStorage; window.loadSavedBanner = loadSavedBanner; window.initializeEventListeners = initializeEventListeners; window.showProcessNotifications = showProcessNotifications; window.handleLogout = handleLogout; window.initializeEventListeners = initializeEventListeners; window.loadSavedBanner = loadSavedBanner; window.initAccount = initAccount; window.openAvatarPopup = openAvatarPopup; // Fonction d'initialisation pour le router export function initAccount(): void { const savedName = localStorage.getItem('userName') || 'Luke'; const savedLastName = localStorage.getItem('userLastName') || 'Doe'; const userNameElement = document.querySelector('.user-name'); const userLastNameElement = document.querySelector('.user-lastname'); if (userNameElement) { userNameElement.textContent = savedName; } if (userLastNameElement) { userLastNameElement.textContent = savedLastName; } initializeEventListeners(); loadSavedBanner(); if (!localStorage.getItem('rows')) { localStorage.setItem('rows', JSON.stringify(defaultRows)); } } // Expose all necessary functions to window window.showPairing = showPairing; window.showWallet = showWallet; window.showProcess = showProcess; window.showData = showData; // Initialize when the document is loaded document.addEventListener('DOMContentLoaded', () => { initAccount(); showPairing(); });