import { g as getCorrectDOM } from './document.utils-SxcZpxzG.mjs'; import { S as Services } from './index-C1Gp83RD.mjs'; const signatureStyle = "/* Styles de base */\n:root {\n --primary-color: #3A506B;\n /* Bleu métallique */\n --secondary-color: #B0BEC5;\n /* Gris acier */\n --accent-color: #D68C45;\n /* Cuivre */\n}\n\nbody {\n font-family: Arial, sans-serif;\n margin: 0;\n padding: 0;\n display: flex;\n height: 100vh;\n background-color: #e9edf1;\n flex-direction: column;\n}\n\n\n\n/* 4NK NAVBAR */\n\n.brand-logo {\n text-align: center;\n font-size: 1.5em;\n font-weight: bold;\n}\n\n.nav-wrapper {\n position: fixed;\n background: radial-gradient(circle, white, var(--primary-color));\n display: flex;\n justify-content: space-between;\n align-items: center;\n color: #37474F;\n height: 9vh;\n width: 100vw;\n left: 0;\n top: 0;\n box-shadow: 0px 8px 10px -5px rgba(0, 0, 0, .2), 0px 16px 24px 2px rgba(0, 0, 0, .14), 0px 6px 30px 5px rgba(0, 0, 0, .12);\n}\n\n/* Icônes de la barre de navigation */\n.nav-right-icons {\n display: flex;\n}\n\n.notification-bell,\n.burger-menu {\n height: 20px;\n width: 20px;\n margin-right: 1rem;\n cursor: pointer;\n}\n\n.notification-container {\n position: relative;\n /* Conserve la position pour le notification-board */\n display: inline-flex;\n align-items: center;\n}\n\n.notification-board {\n position: absolute;\n /* Position absolue pour le placer par rapport au container */\n top: 40px;\n right: 0;\n background-color: white;\n border: 1px solid #ccc;\n padding: 10px;\n width: 200px;\n max-height: 300px;\n overflow-y: auto;\n /* Scroll si les notifications dépassent la taille */\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n z-index: 10;\n /* Définit la priorité d'affichage au-dessus des autres éléments */\n display: none;\n /* Par défaut, la notification est masquée */\n}\n\n.notification-item{\n cursor: pointer;\n}\n\n.notification-badge {\n position: absolute;\n top: -18px;\n right: 35px;\n background-color: red;\n color: white;\n border-radius: 50%;\n padding: 4px 8px;\n font-size: 12px;\n display: none;\n /* S'affiche seulement lorsqu'il y a des notifications */\n z-index: 10;\n}\n\n/* Par défaut, le menu est masqué */\n#menu {\n display: none;\n /* Menu caché par défaut */\n transition: display 0.3s ease-in-out;\n}\n\n.burger-menu {\n cursor: pointer;\n}\n\n/* Icône burger */\n#burger-icon {\n cursor: pointer;\n}\n\n.menu-content {\n display: none;\n position: absolute;\n top: 3.4rem;\n right: 1rem;\n background-color: white;\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n border-radius: 5px;\n overflow: hidden;\n}\n\n.menu-content a {\n display: block;\n padding: 10px 20px;\n text-decoration: none;\n color: #333;\n border-bottom: 1px solid #e0e0e0;\n\n &:hover {\n background-color: rgba(26, 28, 24, .08);\n }\n}\n\n.menu-content a:last-child {\n border-bottom: none;\n}\n\n/* Ajustement pour la barre de navigation fixe */\n.container {\n display: flex;\n flex: 1;\n height: 90vh;\n margin-top: 9vh;\n margin-left: -1%;\n text-align: left;\n width: 209vh;\n}\n\n\n/* Liste des groupes */\n\n.group-list {\n width: 25%;\n background-color: #1f2c3d;\n color: white;\n padding: 20px;\n box-sizing: border-box;\n overflow-y: auto;\n border-right: 2px solid #2c3e50;\n flex-shrink: 0;\n padding-right: 10px;\n height: 91vh;\n}\n\n.group-list ul {\n cursor: pointer;\n list-style: none;\n padding: 0;\n padding-right: 10px;\n margin-left: 20px;\n}\n\n.group-list li {\n margin-bottom: 10px;\n padding: 15px;\n border-radius: 8px;\n background-color: #273646;\n cursor: pointer;\n transition: background-color 0.3s, box-shadow 0.3s;\n}\n\n.group-list li:hover {\n background-color: #34495e;\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);\n}\n\n\n/* Zone de chat */\n\n.chat-area {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n background-color: #ffffff;\n border-radius: 10px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);\n margin: 0px;\n margin-top: 20px;\n margin-left: 1%;\n margin-bottom: -7px;\n}\n\n/* En-tête du chat */\n.chat-header {\n background-color: #34495e;\n color: white;\n padding: 15px;\n font-size: 20px;\n font-weight: bold;\n border-radius: 10px 10px 0 0;\n text-align: center;\n}\n\n/* Messages */\n.messages {\n flex: 1;\n padding: 20px;\n overflow-y: auto;\n background-color: #f1f1f1;\n border-top: 1px solid #ddd;\n}\n\n.message-container {\n max-width: 100%;\n border-radius: 5px;\n overflow-wrap: break-word;\n word-wrap: break-word;\n background-color: #f1f1f1;\n display: flex; \n flex-direction: column; \n}\n\n.message-container .message {\n align-self: flex-start; \n}\n\n.message-container .message.user {\n align-self: flex-end; \n margin-left: auto; \n color: white;\n}\n\n.message {\n padding: 12px 18px;\n background-color: #e1e1e1;\n border-radius: 15px;\n max-width: 70%;\n font-size: 16px;\n line-height: 1.4;\n margin-bottom: 0%;\n white-space: pre-wrap;\n word-wrap: break-word;\n position: relative;\n display: inline-block;\n}\n\n/* Messages de l'utilisateur */\n.message.user {\n background-color: #3498db;\n color: white;\n align-self: flex-end;\n text-align: right;\n}\n\n/* Amélioration de l'esthétique des messages */\n/* .message.user:before {\n content: '';\n position: absolute;\n top: 10px;\n right: -10px;\n border: 10px solid transparent;\n border-left-color: #3498db;\n} */\n\n/* Zone de saisie */\n.input-area {\n padding: 10px;\n background-color: #bdc3c7;\n display: flex;\n align-items: center;\n /* Alignement vertical */\n}\n\n.input-area input[type=\"text\"] {\n flex: 1;\n /* Prend l'espace restant */\n padding: 10px;\n border: 1px solid #ccc;\n border-radius: 5px;\n}\n\n.input-area .attachment-icon {\n margin: 0 10px;\n cursor: pointer;\n display: flex;\n align-items: center;\n}\n\n.input-area button {\n padding: 10px;\n margin-left: 10px;\n background-color: #2980b9;\n color: white;\n border: none;\n border-radius: 5px;\n cursor: pointer;\n}\n\n.input-area button:hover {\n background-color: #1f608d;\n}\n\n#message-input {\n width: 100%;\n height: 50px;\n resize: none;\n padding: 10px;\n box-sizing: border-box;\n overflow: auto;\n max-width: 100%;\n border-radius: 10px;\n}\n\n/* Responsive */\n@media screen and (max-width: 768px) {\n .group-list {\n display: none;\n /* Masquer la liste des groupes sur les petits écrans */\n }\n\n .chat-area {\n margin: 0;\n }\n}\n\n#process-details {\n flex: 1;\n background: white;\n border-radius: 8px;\n margin: 10px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n display: none;\n overflow: hidden;\n}\n\n.process-details-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 20px;\n background: #f8f9fa;\n border-bottom: 1px solid #eee;\n border-radius: 8px 8px 0 0;\n}\n\n.process-details-header h2 {\n margin: 0;\n color: #333;\n}\n\n.close-btn {\n background: none;\n border: none;\n font-size: 24px;\n cursor: pointer;\n color: #666;\n}\n\n.close-btn:hover {\n color: #333;\n}\n\n.process-details-content {\n padding: 20px;\n overflow-y: auto;\n height: calc(100% - 70px);\n}\n\n.details-section {\n margin-bottom: 30px;\n}\n\n.details-section h3 {\n color: #444;\n margin-bottom: 15px;\n padding-bottom: 8px;\n border-bottom: 2px solid #f0f0f0;\n}\n\n.documents-list {\n list-style: none;\n padding: 0;\n}\n\n.documents-list li {\n padding: 8px 0;\n border-bottom: 1px solid #eee;\n}\n\n.roles-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n gap: 20px;\n}\n\n.role-block {\n background: #f8f9fa;\n border-radius: 8px;\n padding: 15px;\n border: 1px solid #eee;\n}\n\n.role-block h4 {\n color: #555;\n margin: 0 0 10px 0;\n padding-bottom: 8px;\n border-bottom: 1px solid #eee;\n}\n\n.members-list {\n list-style: none;\n padding: 0;\n}\n\n.members-list li {\n padding: 8px 12px;\n margin: 4px 0;\n cursor: pointer;\n border-radius: 4px;\n transition: background-color 0.2s;\n}\n\n.members-list li:hover {\n background-color: #e9ecef;\n}\n\n.group-list-item {\n padding: 8px 16px;\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n}\n\n.group-item-container {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n}\n\n.process-name {\n flex-grow: 1;\n cursor: pointer;\n}\n\n.settings-icon {\n cursor: pointer;\n padding: 5px 8px;\n margin-left: 10px;\n border-radius: 4px;\n}\n\n.settings-icon:hover {\n background-color: rgba(255, 255, 255, 0.1);\n}\n\n.process-details {\n position: fixed;\n top: 9vh;\n right: 0;\n bottom: 0;\n left: 23.5%;\n background-color: white;\n box-sizing: border-box;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n border-radius: 8px;\n margin: 10px;\n z-index: 990;\n}\n\n.process-details-content {\n height: calc(100% - 60px); /* Ajusté pour tenir compte du header */\n overflow-y: auto;\n padding: 20px;\n}\n\n.documents-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 20px;\n margin-top: 15px;\n}\n\n.document-card {\n background: white;\n border-radius: 8px;\n padding: 15px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n border: 1px solid #eee;\n}\n\n.document-card.public {\n border-left: 4px solid #4CAF50;\n}\n\n.document-card.private {\n border-left: 4px solid #FFC107;\n}\n\n.document-card.confidential {\n border-left: 4px solid #F44336;\n}\n\n.document-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 10px;\n padding-bottom: 10px;\n border-bottom: 1px solid #eee;\n}\n\n.document-header h4 {\n margin: 0;\n color: #333;\n}\n\n.document-visibility {\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 12px;\n font-weight: bold;\n}\n\n.public .document-visibility {\n background-color: #E8F5E9;\n color: #2E7D32;\n}\n\n.private .document-visibility {\n background-color: #FFF3E0;\n color: #F57C00;\n}\n\n.confidential .document-visibility {\n background-color: #FFEBEE;\n color: #C62828;\n}\n\n.document-info {\n margin: 10px 0;\n font-size: 14px;\n color: #666;\n}\n\n.document-info p {\n margin: 5px 0;\n}\n\n.signatures-list {\n margin-top: 10px;\n}\n\n.signature-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px;\n border-radius: 4px;\n margin: 5px 0;\n background-color: #f8f9fa;\n}\n\n.signature-item.signed {\n background-color: #E8F5E9;\n}\n\n.signature-item.pending {\n background-color: #FFF3E0;\n}\n\n.signer-name {\n font-weight: 500;\n}\n\n.signature-status {\n font-size: 12px;\n}\n\n.signed .signature-status {\n color: #2E7D32;\n}\n\n.pending .signature-status {\n color: #F57C00;\n}\n\n.user-selector {\n position: relative;\n margin-right: 20px;\n}\n\n#userSwitchBtn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 8px 12px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n color: var(--primary-color);\n}\n\n#userSwitchBtn:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.current-user-info {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.user-avatar {\n background-color: var(--primary-color);\n color: white;\n width: 32px;\n height: 32px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: bold;\n}\n\n.user-list {\n position: absolute;\n top: 100%;\n right: 0;\n background: white;\n border-radius: 4px;\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n display: none;\n z-index: 1000;\n max-height: 400px;\n overflow-y: auto;\n width: 250px;\n}\n\n.user-list.show {\n display: block;\n}\n\n.user-list-item {\n padding: 8px 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n}\n\n.user-list-item:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.user-list-item .user-avatar {\n width: 24px;\n height: 24px;\n font-size: 12px;\n}\n\n.user-list-item .user-email {\n font-size: 12px;\n color: #666;\n display: block;\n}\n\n.document-card {\n margin-bottom: 20px;\n padding: 10px;\n border: 1px solid #ccc;\n border-radius: 5px;\n}\n\n.progress-bar {\n background-color: #f3f3f3;\n border-radius: 5px;\n height: 10px;\n width: 100%;\n margin-top: 5px;\n}\n\n.progress {\n background-color: #4caf50; /* Couleur de la barre de progression */\n height: 100%;\n border-radius: 5px;\n}\n\n.new-request-btn {\n background-color: #4caf50; \n color: white; \n border: none;\n border-radius: 5px; \n padding: 10px 15px; \n cursor: pointer; \n margin-left: 10px;\n}\n\n.new-request-btn:hover {\n background-color: #45a049; \n}\n\n.header-buttons {\n display: flex;\n align-items: center; \n gap: 10px; \n}\n\n.close-btn {\n background: none;\n border: none;\n font-size: 24px;\n cursor: pointer;\n color: #666;\n}\n\n.close-btn:hover {\n color: #333;\n}\n\n.new-request-view {\n padding: 20px;\n background-color: white;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n margin: 20px;\n}\n\n.upload-area {\n border: 2px dashed #ccc;\n padding: 20px;\n text-align: center;\n margin: 20px 0;\n}\n\n.upload-icon {\n font-size: 50px;\n margin: 10px 0;\n}\n\n/* New Request View */\n.new-request-view {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: white;\n z-index: 1000; \n padding: 20px;\n box-sizing: border-box;\n overflow-y: auto;\n}\n\n.upload-area {\n border: 2px dashed #ccc;\n padding: 40px;\n text-align: center;\n margin: 20px auto;\n max-width: 600px;\n background-color: #f9f9f9;\n border-radius: 8px;\n cursor: pointer;\n}\n\n.upload-icon {\n font-size: 50px;\n margin: 20px 0;\n}\n\n.new-request-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-top: 60px;\n padding: 0 20px;\n}\n\n.upload-area {\n border: 2px dashed #ccc;\n padding: 40px;\n text-align: center;\n margin: 20px auto;\n max-width: 600px;\n background-color: #f9f9f9;\n border-radius: 8px;\n cursor: pointer;\n}\n\n.details-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n background-color: #f8f9fa;\n padding: 5px 20px;\n border-radius:20px;\n}\n\n.header-buttons {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-direction: row; \n}\n\n.close-btn {\n background: none;\n border: none;\n font-size: 24px;\n cursor: pointer;\n color: #666;\n padding: 5px;\n}\n\n.close-btn:hover {\n color: #333;\n}\n\n.new-request-btn {\n background-color: #4caf50;\n color: white;\n border: none;\n border-radius: 5px;\n padding: 8px 16px;\n cursor: pointer;\n /* margin-left: 10px; <- Supprimez cette ligne si elle existe */\n}\n\n.new-request-btn:hover {\n background-color: #45a049;\n}\n\n/* Ajoutez ces styles à votre fichier CSS existant */\n.document-card.vierge {\n background-color: #fff3cd;\n border: 2px solid #ffeeba;\n}\n\n.document-card.vierge .document-header {\n background-color: #fff3cd;\n}\n\n.document-card.vierge h4 {\n color: #856404;\n}\n\n.document-card.vierge .document-info {\n color: #856404;\n}\n\n/* Style pour l'emoji d'avertissement */\n.document-card.vierge h4::before {\n margin-right: 8px;\n}\n\n.vierge-documents-container {\n padding: 20px;\n overflow-y: auto;\n max-height: calc(100vh - 150px);\n}\n\n.document-form {\n padding: 15px;\n background-color: #fff;\n border-radius: 0 0 5px 5px;\n display: flex;\n gap: 20px;\n}\n\n.form-left {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 15px;\n}\n\n.form-right {\n display: flex;\n flex-direction: column;\n align-items: flex-end; /* Aligner le bouton à droite */\n}\n\n.form-group {\n flex: 2;\n display: flex;\n flex-direction: column;\n margin-bottom: 15px;\n}\n\n.form-group-members {\n flex: 2;\n display: flex;\n flex-direction: column;\n margin-bottom: 15px;\n font-weight: bold;\n}\n\n.submit-btn {\n background-color: #4caf50; \n color: white; \n border: none;\n border-radius: 5px; \n padding: 10px 15px; \n cursor: pointer; \n margin-left: 47%;\n margin-top: 20px;\n}\n\n.submit-btn:hover {\n background-color: #45a049;\n}\n\n.upload-format {\n font-size: 12px;\n color: #666;\n margin: 5px 0;\n}\n\n.browse-btn {\n background-color: #4caf50;\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: 4px;\n cursor: pointer;\n margin-top: 10px;\n}\n\n.browse-btn:hover {\n background-color: #45a049;\n}\n\n.document-selector {\n padding: 20px;\n margin-bottom: 20px;\n}\n\n.document-selector label {\n display: block;\n margin-bottom: 10px;\n font-weight: bold;\n color: #666;\n}\n\n.document-selector select {\n width: 100%;\n padding: 10px;\n border: 1px solid #ddd;\n border-radius: 4px;\n font-size: 16px;\n background-color: white;\n}\n\n#selected-document-form {\n padding: 0 20px;\n overflow: auto;\n height: 65%;\n}\n\n/* Style pour l'option avec l'emoji */\n.document-selector select option {\n padding: 10px;\n font-size: 14px;\n}\n\n.members-selection {\n max-height: 200px;\n overflow-y: auto;\n border: 1px solid #ddd;\n border-radius: 4px;\n padding: 10px;\n background-color: white;\n}\n\n.member-checkbox {\n display: flex;\n align-items: center;\n margin-bottom: 8px;\n padding: 5px;\n}\n\n.member-checkbox:hover {\n background-color: #f5f5f5;\n}\n\n.member-checkbox input[type=\"checkbox\"] {\n margin-right: 10px;\n}\n\n.member-checkbox label {\n cursor: pointer;\n flex: 1;\n}\n\n/* Style pour le conteneur des membres */\n.members-selection-container {\n display: flex;\n flex-direction: column;\n align-items: center; /* Centrer la liste des membres */\n width: 100%;\n}\n\n#members-list {\n width: 60%;\n height: 100%;\n margin-bottom: -40px;\n margin-top: 10px;\n}\n\n/* Style pour le label des membres */\n.members-selection-container label {\n font-weight: bold; /* Mettre le texte en gras */\n margin-bottom: 10px; /* Espacement en bas */\n display: block; /* Affichage en bloc */\n}\n\n/* Style pour les cases à cocher des membres */\n.member-checkbox {\n display: flex;\n align-items: center;\n margin-bottom: 8px;\n padding: 5px;\n border-radius: 4px; /* Coins arrondis */\n transition: background-color 0.2s; /* Transition pour l'effet de survol */\n}\n\n.member-checkbox:hover {\n background-color: #e9ecef; /* Couleur de fond au survol */\n}\n\n/* Style pour les labels */\n.form-group label {\n font-weight: bold; \n margin-bottom: 5px; \n}\n\n/* Style pour les champs de saisie */\n.form-group input,\n.form-group select {\n padding: 10px;\n border: 1px solid #ddd;\n border-radius: 4px;\n font-size: 16px;\n width: 80%;\n}\n\n.add-members-btn {\n background-color: #4caf50; \n color: white; \n border: none; \n border-radius: 5px; \n padding: 10px 15px; \n cursor: pointer; \n margin-top: 10px; /* Espacement au-dessus du bouton */\n}\n\n.add-members-btn:hover {\n background-color: #45a049; \n}\n\n/* Styles pour l'overlay et la modale */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n z-index: 999;\n}\n\n.modal {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background-color: white;\n padding: 20px;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n z-index: 1000;\n width: 25%;\n max-width: 500px;\n}\n\n.modal-content {\n max-height: 70vh;\n overflow-y: auto;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n margin-top: 20px;\n padding-top: 10px;\n border-top: 1px solid #eee;\n}\n\n.confirm-btn {\n background-color: #4caf50;\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.confirm-btn:hover {\n background-color: #45a049;\n}\n\n.selected-member {\n display: flex;\n justify-content: space-between;\n align-items: center;\n background-color: #f5f5f5;\n padding: 8px 12px;\n margin: 4px 0;\n border-radius: 4px;\n}\n\n.cancel-btn {\n background-color: #df2020; \n color: white; \n border: none;\n padding: 8px 16px; \n border-radius: 4px; \n cursor: pointer;\n}\n\n.cancel-btn:hover {\n background-color: #c62828; /\n}\n\n.remove-member-btn {\n background-color: #dc3545;\n color: white;\n border: none;\n border-radius: 50%;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 16px;\n padding: 0;\n margin-left: 8px;\n}\n\n.remove-member-btn:hover {\n background-color: #c82333;\n}\n\n#description {\n height: 100px;\n width: 100%;\n border-radius: 20px;\n padding: 10px 0;\n padding-left: 10px;\n resize: none;\n\n}\n\n.role-item-container {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n padding: 5px 0;\n}\n\n.role-item-container span:last-child {\n margin-left: 10px;\n}\n\n.document-card .new-request-btn {\n margin-top: 60%;\n margin-left: 65%;\n padding: 6px 12px;\n background-color: #4CAF50;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 0.9em;\n}\n\n.document-card .new-request-btn:hover {\n background-color: #45a049;\n}\n\n/* Styles pour la modale de nouveau document */\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n}\n\n\n.modal-content-document {\n background: white;\n padding: 20px;\n border-radius: 8px;\n width: 97%;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n padding-bottom: 10px;\n border-bottom: 1px solid #eee;\n}\n\n.modal-header h2 {\n margin: 0;\n color: #333;\n}\n\n.modal-body {\n margin-bottom: 20px;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n padding-top: 20px;\n border-top: 1px solid #eee;\n}\n\n.modal-document {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n}\n.form-group {\n margin-bottom: 15px;\n}\n\n.form-group label {\n display: block;\n margin-bottom: 5px;\n font-weight: bold;\n color: #555;\n}\n\n.form-control {\n width: 100%;\n padding: 8px;\n border: 1px solid #ddd;\n border-radius: 4px;\n font-size: 14px;\n}\n\n.form-row {\n display: flex;\n gap: 15px;\n margin-bottom: 15px;\n}\n\n.form-group.half {\n flex: 1;\n margin-bottom: 0; /* Annule la marge du form-group standard */\n}\n\n.selected-signatories {\n margin: 10px 0;\n padding: 10px;\n border: 1px solid #ddd;\n border-radius: 4px;\n min-height: 50px;\n}\n\n.signatory-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 5px;\n margin: 5px 0;\n background: #f5f5f5;\n border-radius: 4px;\n}\n\n.remove-btn {\n background: none;\n border: none;\n color: #dc3545;\n cursor: pointer;\n font-size: 18px;\n padding: 0 5px;\n}\n\n.remove-btn:hover {\n color: #bd2130;\n}\n\n.btn-primary {\n background: #4CAF50;\n color: white;\n padding: 10px 20px;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.btn-primary:hover {\n background: #45a049;\n}\n\n.btn-secondary {\n background: #6c757d;\n color: white;\n padding: 8px 15px;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.btn-secondary:hover {\n background: #5a6268;\n}\n\n.signatories-list {\n max-height: 300px;\n overflow-y: auto;\n}\n\n.signatory-option {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px;\n border-bottom: 1px solid #eee;\n}\n\n.role-select {\n padding: 4px;\n border: 1px solid #ddd;\n border-radius: 4px;\n margin-left: auto;\n}\n\n.role-section {\n margin-bottom: 20px;\n padding: 10px;\n background: #f8f9fa;\n border-radius: 4px;\n}\n\n.role-section h4 {\n margin: 0 0 10px 0;\n color: #495057;\n}\n\n.members-selection {\n max-height: 300px;\n overflow-y: auto;\n padding: 10px;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n}\n\ninput[type=\"file\"] {\n padding: 10px;\n border: 1px dashed #ccc;\n border-radius: 4px;\n width: 100%;\n margin-top: 5px;\n}\n\n.file-upload-container {\n border: 2px dashed #ccc;\n padding: 20px;\n text-align: center;\n margin: 10px 0;\n border-radius: 5px;\n cursor: pointer;\n}\n\n.file-upload-container:hover {\n background-color: #f5f5f5;\n border-color: #666;\n}\n\n.file-upload-container.dragover {\n background-color: #f0f0f0;\n border-color: #4CAF50;\n}\n\n.file-list {\n margin-top: 10px;\n}\n\n.file-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px;\n margin: 5px 0;\n background: #f5f5f5;\n border-radius: 4px;\n}\n\n.file-info {\n display: flex;\n gap: 10px;\n align-items: center;\n}\n\n.remove-file {\n background: none;\n border: none;\n color: #ff4444;\n cursor: pointer;\n font-size: 18px;\n}\n\n#fileInput {\n display: none;\n}\n\n.required-signatories {\n margin: 10px 0;\n}\n\n.signatory-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px;\n margin: 5px 0;\n background: #f5f5f5;\n border-radius: 4px;\n}\n\n.signatory-item.locked {\n background: #e8e8e8;\n cursor: not-allowed;\n}\n\n.member-name {\n font-weight: 500;\n}\n\n.role-info {\n color: #666;\n font-size: 0.9em;\n}\n\n.lock-icon {\n margin-left: auto;\n opacity: 0.6;\n}\n\n/* Style pour la popup d'alerte */\n.alert-popup {\n position: fixed;\n top: 20px;\n left: 50%;\n transform: translateX(-50%);\n background-color: #f44336;\n color: white;\n padding: 15px 25px;\n border-radius: 4px;\n box-shadow: 0 2px 5px rgba(0,0,0,0.2);\n z-index: 1000;\n display: none;\n animation: slideDown 0.3s ease-out;\n}\n\n.sign-button {\n background-color: #4CAF50;\n color: white;\n padding: 8px 16px;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n margin-top: 10px;\n}\n\n.sign-button:hover {\n background-color: #45a049;\n}\n\n.sign-button:disabled {\n background-color: #cccccc;\n cursor: not-allowed;\n}\n\n.modal-document {\n background: white;\n border-radius: 8px;\n max-width: 800px;\n width: 90%;\n max-height: 95vh;\n overflow-y: auto;\n position: relative;\n}\n\n.document-details {\n padding: 20px;\n}\n\n.info-section {\n margin: 20px 0;\n background: #f8f9fa;\n padding: 15px;\n border-radius: 6px;\n}\n\n.info-row {\n display: flex;\n justify-content: space-between;\n margin-bottom: 10px;\n}\n\n.label {\n font-weight: bold;\n color: #666;\n}\n\n.description-section {\n margin: 20px 0;\n}\n\n.signatures-section {\n margin: 20px 0;\n}\n\n.signature-item {\n display: flex;\n justify-content: space-between;\n padding: 8px;\n border-bottom: 1px solid #eee;\n}\n\n.signature-item.signed {\n background-color: #e8f5e9;\n}\n\n.signature-item.pending {\n background-color: #fff3e0;\n}\n\n.files-section {\n margin: 20px 0;\n}\n\n.file-item {\n display: flex;\n align-items: center;\n padding: 8px;\n background: #f8f9fa;\n margin-bottom: 5px;\n border-radius: 4px;\n}\n\n.file-icon {\n margin-right: 10px;\n}\n\n.download-link {\n margin-left: auto;\n}\n\n.confirmation-section {\n margin-top: 30px;\n text-align: center;\n}\n\n.warning-text {\n color: #f44336;\n margin-bottom: 15px;\n}\n\n.sign-confirm-btn {\n background-color: #4CAF50;\n color: white;\n padding: 10px 20px;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.sign-confirm-btn:hover {\n background-color: #45a049;\n}\n\n.signature-slider-container {\n margin: 20px 20%;\n padding: 10px;\n}\n\n.slider-track {\n position: relative;\n background: #e0e0e0;\n height: 40px;\n border-radius: 20px;\n display: flex;\n align-items: center;\n overflow: hidden;\n}\n\n.slider-handle {\n position: absolute;\n left: 0;\n width: 40px;\n height: 40px;\n background: #4CAF50;\n border-radius: 50%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n touch-action: none;\n z-index: 1;\n}\n\n.slider-arrow {\n color: white;\n font-size: 20px;\n}\n\n.slider-text {\n width: 100%;\n text-align: center;\n color: #666;\n user-select: none;\n}"; // Définir les rôles autorisés const VISIBILITY_LEVELS = { PUBLIC: 'public', CONFIDENTIAL: 'confidential', PRIVATE: 'private', }; const DOCUMENT_STATUS = { DRAFT: 'draft', PENDING: 'pending'}; const groupsMock = [ { id: 1, name: 'Processus 1', description: 'Description du processus 1', commonDocuments: [ { id: 101, name: 'Règlement intérieur', description: 'Document vierge pour le règlement intérieur', visibility: VISIBILITY_LEVELS.PUBLIC, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 102, name: 'Charte de confidentialité', description: 'Document vierge pour la charte de confidentialité', visibility: VISIBILITY_LEVELS.CONFIDENTIAL, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 103, name: 'Procédures générales', description: 'Document vierge pour les procédures générales', visibility: VISIBILITY_LEVELS.PUBLIC, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 104, name: 'Urgency A', description: "Document vierge pour le plan d'urgence A", visibility: VISIBILITY_LEVELS.PRIVATE, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 105, name: 'Urgency B', description: "Document vierge pour le plan d'urgence B", visibility: VISIBILITY_LEVELS.PRIVATE, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 106, name: 'Urgency C', description: "Document vierge pour le plan d'urgence C", visibility: VISIBILITY_LEVELS.PRIVATE, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 107, name: 'Document à signer', description: 'Document vierge pour le règlement intérieur', visibility: VISIBILITY_LEVELS.PUBLIC, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, ], roles: [ { name: 'User', members: [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, ], documents: [ { id: 1, name: 'Document User A', description: 'Description du document User A.', visibility: 'public', createdAt: '2024-01-01', deadline: '2024-02-01', signatures: [ { member: { id: 1, name: 'Alice' }, signed: true, signedAt: '2024-01-15', }, { member: { id: 2, name: 'Bob' }, signed: false, }, ], }, { id: 2, name: 'Document User B', description: 'Document vierge pour le rôle User', visibility: 'confidential', createdAt: null, deadline: null, signatures: [], }, { id: 7, name: 'Document User C', description: 'Document vierge pour validation utilisateur', visibility: VISIBILITY_LEVELS.CONFIDENTIAL, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 8, name: 'Document User D', description: 'Document vierge pour approbation utilisateur', visibility: VISIBILITY_LEVELS.PUBLIC, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, ], }, { name: 'Process', members: [ { id: 3, name: 'Charlie' }, { id: 4, name: 'David' }, ], documents: [ { id: 3, name: 'Document Process A', description: 'Description du document Process A.', visibility: 'confidential', createdAt: '2024-01-10', deadline: '2024-03-01', signatures: [ { member: { id: 3, name: 'Charlie' }, signed: true, signedAt: '2024-01-12', }, ], }, { id: 9, name: 'Document Process B', description: 'Document vierge pour processus interne', visibility: VISIBILITY_LEVELS.CONFIDENTIAL, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 10, name: 'Document Process C', description: 'Document vierge pour validation processus', visibility: VISIBILITY_LEVELS.PRIVATE, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 11, name: 'Document Process D', description: 'Document vierge pour validation processus', visibility: VISIBILITY_LEVELS.PUBLIC, status: DOCUMENT_STATUS.PENDING, createdAt: '2024-01-15', deadline: '2024-02-01', signatures: [ { member: { id: 3, name: 'Charlie' }, signed: true, signedAt: '2024-01-15', }, { member: { id: 4, name: 'David' }, signed: false, }, ], }, { id: 12, name: 'Document Process E', description: 'Document vierge pour validation processus', visibility: VISIBILITY_LEVELS.PUBLIC, status: DOCUMENT_STATUS.PENDING, createdAt: '2024-01-15', deadline: '2024-02-01', signatures: [ { member: { id: 3, name: 'Charlie' }, signed: true, signedAt: '2024-01-15', }, { member: { id: 4, name: 'David' }, signed: false, }, ], }, ], }, { name: 'Backup', members: [ { id: 15, name: 'Oscar' }, { id: 16, name: 'Patricia' }, ], documents: [ { id: 11, name: 'Document Backup A', description: 'Document vierge pour sauvegarde', visibility: VISIBILITY_LEVELS.PRIVATE, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, ], }, ], }, { id: 2, name: 'Processus 2', description: 'Description du processus 2', commonDocuments: [ { id: 201, name: 'Règlement intérieur', description: 'Document vierge pour le règlement intérieur', visibility: VISIBILITY_LEVELS.PUBLIC, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 202, name: 'Charte de confidentialité', description: 'Document vierge pour la charte de confidentialité', visibility: VISIBILITY_LEVELS.CONFIDENTIAL, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 203, name: 'Charte de confidentialité', description: 'Document vierge pour la charte de confidentialité', visibility: VISIBILITY_LEVELS.PRIVATE, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 204, name: 'Charte de confidentialité', description: 'Document vierge pour la charte de confidentialité', visibility: VISIBILITY_LEVELS.PRIVATE, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 205, name: 'Charte de confidentialité', description: 'Document vierge pour la charte de confidentialité', visibility: VISIBILITY_LEVELS.PRIVATE, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, ], roles: [ { name: 'Artefact', members: [ { id: 17, name: 'Quinn' }, { id: 18, name: 'Rachel' }, ], documents: [ { id: 12, name: 'Document Artefact A', description: 'Document vierge pour artefact', visibility: VISIBILITY_LEVELS.CONFIDENTIAL, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 13, name: 'Document Artefact B', description: 'Document vierge pour validation artefact', visibility: VISIBILITY_LEVELS.PRIVATE, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, ], }, { name: 'Resolve', members: [ { id: 19, name: 'Sam' }, { id: 20, name: 'Tom' }, ], documents: [ { id: 14, name: 'Document Resolve A', description: 'Document vierge pour résolution', visibility: VISIBILITY_LEVELS.CONFIDENTIAL, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, ], }, ], }, { id: 3, name: 'Processus 3', description: 'Description du processus 3', commonDocuments: [ { id: 301, name: 'Règlement intérieur', description: 'Document vierge pour le règlement intérieur', visibility: VISIBILITY_LEVELS.PUBLIC, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 302, name: 'Charte de confidentialité', description: 'Document vierge pour la charte de confidentialité', visibility: VISIBILITY_LEVELS.CONFIDENTIAL, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 303, name: 'Procédures générales', description: 'Document vierge pour les procédures générales', visibility: VISIBILITY_LEVELS.PUBLIC, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, ], roles: [ { name: 'Deposit', members: [ { id: 21, name: 'Uma' }, { id: 22, name: 'Victor' }, ], documents: [ { id: 15, name: 'Document Deposit A', description: 'Document vierge pour dépôt', visibility: VISIBILITY_LEVELS.PRIVATE, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 16, name: 'Document Deposit B', description: 'Document vierge pour validation dépôt', visibility: VISIBILITY_LEVELS.CONFIDENTIAL, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, ], }, { name: 'Payment', members: [ { id: 23, name: 'Walter' }, { id: 24, name: 'Xena' }, ], documents: [ { id: 17, name: 'Document Payment B', description: 'Document vierge pour paiement', visibility: VISIBILITY_LEVELS.PRIVATE, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, { id: 18, name: 'Document Payment C', description: 'Document vierge pour validation paiement', visibility: VISIBILITY_LEVELS.CONFIDENTIAL, status: DOCUMENT_STATUS.DRAFT, createdAt: null, deadline: null, signatures: [], }, ], }, ], }, ]; const messagesMock = [ { memberId: 1, // Conversations avec Mmber 1 messages: [ { id: 1, sender: "Mmeber 1", text: "Salut !", time: "10:30 AM" }, { id: 2, sender: "4NK", text: "Bonjour ! Comment ça va ?", time: "10:31 AM" }, { id: 3, sender: "4NK", text: "Tout va bien, merci !", time: "10:32 AM" } ] }, { memberId: 2, // Conversations avec Member 2 messages: [ { id: 1, sender: "Member 2", text: "Salut, on se voit ce soir ?", time: "10:30 AM" }, { id: 2, sender: "4NK", text: "Oui, à quelle heure ?", time: "10:31 AM" } ] }, { memberId: 3, // Conversations avec Member 3 messages: [ { id: 1, sender: "Member 3", text: "Hey, ça va ?", time: "10:30 AM" }, { id: 2, sender: "4NK", text: "Ça va et toi ?", time: "10:31 AM" } ] }, { memberId: 4, // Conversations avec Member 4 messages: [ { id: 1, sender: "Member 4", text: "Hey, ça va ?", time: "10:30 AM" }, { id: 2, sender: "4NK", text: "Ça va et toi ?", time: "10:31 AM" }, { id: 3, sender: "4NK", text: "Ça va et toi ?", time: "10:31 AM" } ] }, { memberId: 5, // Conversations avec Member 5 messages: [ { id: 1, sender: "Member 5", text: "Hey, ça va ?", time: "10:30 AM" }, { id: 2, sender: "4NK", text: "Ça va et toi ?", time: "10:31 AM" }, { id: 3, sender: "4NK", text: "Ça va et toi ?", time: "10:31 AM" } ] }, { memberId: 6, // Conversations avec Member 6 messages: [ { id: 1, sender: "Member 6", text: "Hey, ça va ?", time: "10:30 AM" }, { id: 2, sender: "4NK", text: "Ça va et toi ?", time: "10:31 AM" }, { id: 3, sender: "4NK", text: "Ça va et toi ?", time: "10:31 AM" } ] }, { memberId: 7, // Conversations avec Member 7 messages: [ { id: 1, sender: "Member 7", text: "Hey, ça va ?", time: "10:30 AM" }, { id: 2, sender: "4NK", text: "Ça va et toi ?", time: "10:31 AM" }, { id: 3, sender: "4NK", text: "Ça va et toi ?", time: "10:31 AM" } ] }, { memberId: 8, // Conversations avec Member 8 messages: [ { id: 1, sender: "Member 8", text: "Hey, ça va ?", time: "10:30 AM" }, { id: 2, sender: "4NK", text: "Ça va et toi ?", time: "10:31 AM" }, { id: 3, sender: "4NK", text: "Ça va et toi ?", time: "10:31 AM" } ] } ]; const membersMock = [ // Processus 1 { id: 1, name: 'Alice', avatar: 'A', email: 'alice@company.com', processRoles: [{ processId: 1, role: 'User' }], }, { id: 2, name: 'Bob', avatar: 'B', email: 'bob@company.com', processRoles: [{ processId: 1, role: 'User' }], }, { id: 3, name: 'Charlie', avatar: 'C', email: 'charlie@company.com', processRoles: [{ processId: 1, role: 'Process' }], }, { id: 4, name: 'David', avatar: 'D', email: 'david@company.com', processRoles: [{ processId: 1, role: 'Process' }], }, { id: 15, name: 'Oscar', avatar: 'O', email: 'oscar@company.com', processRoles: [{ processId: 1, role: 'Backup' }], }, { id: 16, name: 'Patricia', avatar: 'P', email: 'patricia@company.com', processRoles: [{ processId: 1, role: 'Backup' }], }, // Processus 2 { id: 17, name: 'Quinn', avatar: 'Q', email: 'quinn@company.com', processRoles: [{ processId: 2, role: 'Artefact' }], }, { id: 18, name: 'Rachel', avatar: 'R', email: 'rachel@company.com', processRoles: [{ processId: 2, role: 'Artefact' }], }, { id: 19, name: 'Sam', avatar: 'S', email: 'sam@company.com', processRoles: [{ processId: 2, role: 'Resolve' }], }, { id: 20, name: 'Tom', avatar: 'T', email: 'tom@company.com', processRoles: [{ processId: 2, role: 'Resolve' }], }, // Processus 3 { id: 21, name: 'Uma', avatar: 'U', email: 'uma@company.com', processRoles: [{ processId: 3, role: 'Deposit' }], }, { id: 22, name: 'Victor', avatar: 'V', email: 'victor@company.com', processRoles: [{ processId: 3, role: 'Deposit' }], }, { id: 23, name: 'Walter', avatar: 'W', email: 'walter@company.com', processRoles: [{ processId: 3, role: 'Payment' }], }, { id: 24, name: 'Xena', avatar: 'X', email: 'xena@company.com', processRoles: [{ processId: 3, role: 'Payment' }], }, ]; class MessageStore { STORAGE_KEY = "chat_messages"; messages = []; constructor() { this.messages = this.loadFromLocalStorage() || []; } loadFromLocalStorage() { try { const stored = localStorage.getItem(this.STORAGE_KEY); return stored ? JSON.parse(stored) : null; } catch (error) { console.error("Error loading messages:", error); return null; } } getMessages() { return this.messages; } setMessages(messages) { this.messages = messages; this.saveToLocalStorage(); } saveToLocalStorage() { try { localStorage.setItem(this.STORAGE_KEY, JSON.stringify(this.messages)); } catch (error) { console.error("Error saving messages:", error); } } addMessage(memberId, message) { const memberMessages = this.messages.find((m) => String(m.memberId) === String(memberId)); if (memberMessages) { memberMessages.messages.push(message); } else { this.messages.push({ memberId: String(memberId), messages: [message] }); } this.saveToLocalStorage(); } } const messageStore = new MessageStore(); let currentUser = membersMock[0]; class SignatureElement extends HTMLElement { selectedMemberId = null; messagesMock = []; dom; notifications = []; notificationBadge = document.querySelector(".notification-badge"); notificationBoard = document.getElementById("notification-board"); notificationBell = document.getElementById("notification-bell"); selectedSignatories = []; allMembers = membersMock.map((member) => ({ id: member.id, name: member.name, roleName: "Default Role" })); showAlert(message) { let alertPopup = this.shadowRoot?.querySelector(".alert-popup"); if (!alertPopup) { alertPopup = document.createElement("div"); alertPopup.className = "alert-popup"; this.shadowRoot?.appendChild(alertPopup); } alertPopup.textContent = message; alertPopup.style.display = "block"; setTimeout(() => { alertPopup.style.display = "none"; }, 3e3); } signDocument(documentId, processId, isCommonDocument = false) { try { let initDrag = function(e) { isDragging = true; startX = "touches" in e ? e.touches[0].clientX : e.clientX; sliderLeft = slider?.offsetLeft || 0; }, drag = function(e) { if (!isDragging || !slider || !sliderTrack) return; e.preventDefault(); const x = "touches" in e ? e.touches[0].clientX : e.clientX; const deltaX = x - startX; let newLeft = sliderLeft + deltaX; const maxLeft = sliderTrack.offsetWidth - slider.offsetWidth; newLeft = Math.max(0, Math.min(newLeft, maxLeft)); slider.style.left = `${newLeft}px`; if (newLeft > maxLeft * 0.9) { stopDrag(e); this.confirmSignature(documentId, processId, isCommonDocument); } }, stopDrag = function(e) { if (!isDragging || !slider) return; isDragging = false; if (slider.offsetLeft < (sliderTrack?.offsetWidth || 0) * 0.9) { slider.style.left = "0px"; } }; if (typeof window === "undefined" || typeof document === "undefined") { console.error("Cette fonction ne peut être exécutée que dans un navigateur"); return; } const groups = JSON.parse(localStorage.getItem("groups") || JSON.stringify(groupsMock)); const group = groups.find((g) => g.id === processId); if (!group) { throw new Error("Process not found"); } let targetDoc; if (isCommonDocument) { targetDoc = group.commonDocuments.find((d) => d.id === documentId); } else { for (const role of group.roles) { if (role.documents) { targetDoc = role.documents.find((d) => d.id === documentId); if (targetDoc) break; } } } if (!targetDoc) { throw new Error("Document not found"); } const canSign = isCommonDocument ? targetDoc.signatures?.some((sig) => sig.member?.name === currentUser?.name && !sig.signed) : this.canUserSignDocument(targetDoc, currentUser?.name, currentUser); if (!canSign) { this.showAlert("You do not have the necessary rights to sign this document."); return; } const modalHtml = ` `; const modalElement = document.createElement("div"); modalElement.className = "modal-overlay"; modalElement.innerHTML = modalHtml; this.shadowRoot?.appendChild(modalElement); const slider = modalElement.querySelector("#signatureSlider"); const sliderTrack = slider?.parentElement; let isDragging = false; let startX; let sliderLeft; if (slider && sliderTrack) { slider.addEventListener("mousedown", (e) => initDrag(e)); slider.addEventListener("touchstart", (e) => initDrag(e)); modalElement.addEventListener("mousemove", (e) => drag.call(this, e)); modalElement.addEventListener("touchmove", (e) => drag.call(this, e)); modalElement.addEventListener("mouseup", (e) => stopDrag(e)); modalElement.addEventListener("touchend", (e) => stopDrag(e)); } } catch (error) { console.error("Error displaying modal:", error); this.showAlert(error instanceof Error ? error.message : "Error displaying modal"); } } constructor() { super(); this.attachShadow({ mode: "open" }); this.dom = getCorrectDOM("signature-element"); this.shadowRoot.innerHTML = `
`; window.toggleUserList = this.toggleUserList.bind(this); window.switchUser = this.switchUser.bind(this); window.closeProcessDetails = this.closeProcessDetails.bind(this); window.loadMemberChat = this.loadMemberChat.bind(this); window.closeRoleDocuments = this.closeRoleDocuments.bind(this); window.newRequest = this.newRequest.bind(this); window.submitRequest = this.submitRequest.bind(this); window.closeNewRequest = this.closeNewRequest.bind(this); window.closeModal = this.closeModal.bind(this); window.submitNewDocument = this.submitNewDocument.bind(this); window.submitCommonDocument = this.submitCommonDocument.bind(this); window.signDocument = this.signDocument.bind(this); window.confirmSignature = this.confirmSignature.bind(this); window.submitDocumentRequest = this.submitDocumentRequest.bind(this); document.addEventListener("click", (event) => { if (this.notificationBoard && this.notificationBoard.style.display === "block" && !this.notificationBoard.contains(event.target) && this.notificationBell && !this.notificationBell.contains(event.target)) { this.notificationBoard.style.display = "none"; } }); this.initMessageEvents(); this.initFileUpload(); } initMessageEvents() { const sendButton = this.shadowRoot?.getElementById("send-button"); if (sendButton) { sendButton.addEventListener("click", () => this.sendMessage()); } const messageInput = this.shadowRoot?.getElementById("message-input"); if (messageInput) { messageInput.addEventListener("keypress", (event) => { if (event.key === "Enter" && !event.shiftKey) { event.preventDefault(); this.sendMessage(); } }); } } initFileUpload() { const fileInput = this.shadowRoot?.getElementById("file-input"); if (fileInput) { fileInput.addEventListener("change", (event) => { const target = event.target; if (target.files && target.files.length > 0) { this.sendFile(target.files[0]); } }); } } calculateDuration(startDate, endDate) { const start = new Date(startDate || ""); const end = new Date(endDate || ""); const duration = end.getTime() - start.getTime(); return Math.floor(duration / (1e3 * 60 * 60 * 24)); } // Add this helper function canUserAccessDocument(document2, roleId, currentUserRole) { if (document2.visibility === "public") { return true; } return roleId === currentUserRole; } canUserSignDocument(document2, role, user) { console.log("Checking signing rights for:", { document: document2, role, user, userRoles: user.processRoles }); const isSignatory = document2.signatures?.some((sig) => sig.member && "id" in sig.member && sig.member.id === user.id && !sig.signed); if (!isSignatory) { console.log("User is not in signatures list or has already signed"); return false; } return true; } closeProcessDetails(groupId) { const detailsArea = this.shadowRoot?.getElementById(`process-details-${groupId}`); const chatArea = this.shadowRoot?.getElementById("chat-area"); if (detailsArea) { detailsArea.style.display = "none"; } if (chatArea) { chatArea.style.display = "block"; } } ///////////////////// Notification module ///////////////////// // Delete a notification removeNotification(index) { this.notifications?.splice(index, 1); this.renderNotifications(); this.updateNotificationBadge(); } // Show notifications renderNotifications() { if (!this.notificationBoard) return; this.notificationBoard.innerHTML = ""; if (this.notifications.length === 0) { this.notificationBoard.innerHTML = '
No notifications available
'; return; } this.notifications.forEach((notif, index) => { const notifElement = document.createElement("div"); notifElement.className = "notification-item"; notifElement.textContent = `${notif.text} at ${notif.time}`; notifElement.onclick = () => { this.loadMemberChat(notif.memberId); this.removeNotification(index); }; this.notificationBoard?.appendChild(notifElement); }); } updateNotificationBadge() { if (!this.notificationBadge) return; const count = this.notifications.length; this.notificationBadge.textContent = count > 99 ? "+99" : count.toString(); this.notificationBadge.style.display = count > 0 ? "block" : "none"; } // Add notification addNotification(memberId, message) { const notification = { memberId, text: `New message from Member ${memberId}: ${message.text}`, time: message.time }; this.notifications.push(notification); this.renderNotifications(); this.updateNotificationBadge(); } // Send a messsage sendMessage() { const messageInput = this.shadowRoot?.getElementById("message-input"); if (!messageInput) return; const messageText = messageInput.value.trim(); if (messageText === "" || this.selectedMemberId === null) { return; } const newMessage = { id: Date.now(), sender: "4NK", text: messageText, time: (/* @__PURE__ */ new Date()).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }), type: "text" }; messageStore.addMessage(this.selectedMemberId, newMessage); this.messagesMock = messageStore.getMessages(); this.loadMemberChat(this.selectedMemberId); messageInput.value = ""; setTimeout(() => { if (this.selectedMemberId) { const autoReply = this.generateAutoReply(`Member ${this.selectedMemberId}`); messageStore.addMessage(this.selectedMemberId, autoReply); this.messagesMock = messageStore.getMessages(); this.loadMemberChat(this.selectedMemberId); this.addNotification(this.selectedMemberId, autoReply); } }, 2e3); } showProcessDetails(group, groupId) { console.log("Showing details for group:", groupId); const allDetailsAreas = this.shadowRoot?.querySelectorAll(".process-details"); if (allDetailsAreas) { allDetailsAreas.forEach((area) => { area.style.display = "none"; }); } const container = this.shadowRoot?.querySelector(".container"); if (!container) { console.error("Container not found"); return; } const storedGroups = JSON.parse(localStorage.getItem("groups") || "[]"); const storedGroup = storedGroups.find((g) => g.id === groupId); const displayGroup = storedGroup || group; let detailsArea = this.shadowRoot?.getElementById(`process-details-${groupId}`); if (!detailsArea) { detailsArea = document.createElement("div"); detailsArea.id = `process-details-${groupId}`; detailsArea.className = "process-details"; container.appendChild(detailsArea); } if (detailsArea) { detailsArea.style.display = "block"; detailsArea.innerHTML = `

${displayGroup.name}

Description

${displayGroup.description || "No description available"}

Documents Communs

${displayGroup.commonDocuments.map((document2) => { const totalSignatures = document2.signatures?.length || 0; const signedCount = document2.signatures?.filter((sig) => sig.signed).length || 0; const percentage = totalSignatures > 0 ? signedCount / totalSignatures * 100 : 0; const isVierge = !document2.createdAt || !document2.deadline || !document2.signatures?.length; const canSign = document2.signatures?.some((sig) => sig.member && "id" in sig.member && sig.member.id === currentUser.id && !sig.signed); const signButton = !isVierge ? ` ${totalSignatures > 0 && signedCount < totalSignatures && canSign ? ` ` : ""} ` : ""; return `

${isVierge ? `⚠️ ${document2.name}` : document2.name}

${document2.visibility}
${!isVierge ? `

Created on: ${document2.createdAt ? new Date(document2.createdAt).toLocaleDateString() : "N/A"}

Deadline: ${document2.deadline ? new Date(document2.deadline).toLocaleDateString() : "N/A"}

Duration: ${this.calculateDuration(document2.createdAt || "", document2.deadline || "")} days

Signatures:
${document2.signatures?.map((sig) => `
${sig.member.name} ${sig.signed ? `✓ Signed on ${sig.signedAt ? new Date(sig.signedAt).toLocaleDateString() : "unknown date"}` : "⌛ Pending"}
`).join("")}

${signedCount} out of ${totalSignatures} signed (${percentage.toFixed(0)}%)

` : `

Document vierge - Waiting for creation

`} ${signButton}
`; }).join("")}

Roles and Documents

${displayGroup.roles.map((role) => { const accessibleDocuments = (role.documents || []).filter((doc) => this.canUserAccessDocument(doc, role.name, currentUser.processRoles?.[0]?.role || "")); return `

${role.name}

${accessibleDocuments.map((document2) => { const isVierge = !document2.createdAt || !document2.deadline || document2.signatures.length === 0; const canSign = this.canUserSignDocument(document2, role.name, currentUser); const signButton = !isVierge ? ` ${document2.signatures.length > 0 && document2.signatures.filter((sig) => sig.signed).length < document2.signatures.length && canSign ? ` ` : ""} ` : ""; return `

${isVierge ? `⚠️ ${document2.name}` : document2.name}

${document2.visibility}
${!isVierge ? `

Created on: ${document2.createdAt ? new Date(document2.createdAt).toLocaleDateString() : "N/A"}

Deadline: ${document2.deadline ? new Date(document2.deadline).toLocaleDateString() : "N/A"}

Duration: ${this.calculateDuration(document2.createdAt || "", document2.deadline || "")} days

` : "

Document vierge - Waiting for creation

"}
${!isVierge ? `
Signatures:
${document2.signatures.map((sig) => `
${sig.member.name} ${sig.signed ? `✓ Signé le ${sig.signedAt ? new Date(sig.signedAt).toLocaleDateString() : "date inconnue"}` : "⌛ En attente"}
`).join("")}

${document2.signatures.filter((sig) => sig.signed).length} out of ${document2.signatures.length} signed (${(document2.signatures.filter((sig) => sig.signed).length / document2.signatures.length * 100).toFixed(0)}%)

` : ""} ${signButton}
`; }).join("")}
`; }).join("")}

Members by Role

${displayGroup.roles.map((role) => `

${role.name}

    ${role.members.map((member) => `
  • ${member.name}
  • `).join("")}
`).join("")}
`; const newCloseProcessButton = document.createElement("button"); newCloseProcessButton.className = "close-btn"; newCloseProcessButton.textContent = "x"; newCloseProcessButton.addEventListener("click", () => this.closeProcessDetails(groupId)); const headerButtons = detailsArea.querySelector(".header-buttons"); if (headerButtons) { headerButtons.appendChild(newCloseProcessButton); } } } // Scroll down the conversation after loading messages scrollToBottom(container) { container.scrollTop = container.scrollHeight; } // Load the list of members loadMemberChat(memberId) { this.selectedMemberId = String(memberId); const memberMessages = this.messagesMock.find((m) => String(m.memberId) === String(memberId)); let memberInfo = { processName: "", roleName: "", memberName: "" }; groupsMock.forEach((process) => { process.roles.forEach((role) => { const member = role.members.find((m) => String(m.id) === String(memberId)); if (member) { memberInfo = { processName: process.name, roleName: role.name, memberName: member.name }; } }); }); const chatHeader = this.shadowRoot?.getElementById("chat-header"); const messagesContainer = this.shadowRoot?.getElementById("messages"); if (!chatHeader || !messagesContainer) return; chatHeader.textContent = `Chat with ${memberInfo.roleName} ${memberInfo.memberName} from ${memberInfo.processName}`; messagesContainer.innerHTML = ""; if (memberMessages) { memberMessages.messages.forEach((message) => { const messageElement = document.createElement("div"); messageElement.className = "message-container"; const messageContent = document.createElement("div"); messageContent.className = "message"; if (message.type === "file") { messageContent.innerHTML = `${message.fileName}`; messageContent.classList.add("user"); } else { messageContent.innerHTML = `${message.sender}: ${message.text} ${message.time}`; if (message.sender === "4NK") { messageContent.classList.add("user"); } } messageElement.appendChild(messageContent); messagesContainer.appendChild(messageElement); }); } this.scrollToBottom(messagesContainer); } toggleMembers(role, roleElement) { let memberList = roleElement.querySelector(".member-list"); if (memberList) { memberList.style.display = memberList.style.display === "none" ? "block" : "none"; return; } memberList = document.createElement("ul"); memberList.className = "member-list"; role.members.forEach((member) => { const memberItem = document.createElement("li"); memberItem.textContent = member.name; memberItem.onclick = (event) => { event.stopPropagation(); this.loadMemberChat(member.id.toString()); }; memberList.appendChild(memberItem); }); roleElement.appendChild(memberList); } // Toggle the list of Roles toggleRoles(group, groupElement) { console.log("=== toggleRoles START ==="); console.log("Group:", group.name); console.log("Group roles:", group.roles); let roleList = groupElement.querySelector(".role-list"); console.log("Existing roleList:", roleList); if (roleList) { const roleItems = roleList.querySelectorAll(".role-item"); roleItems.forEach((roleItem) => { console.log("Processing roleItem:", roleItem.innerHTML); let container = roleItem.querySelector(".role-item-container"); if (!container) { container = document.createElement("div"); container.className = "role-item-container"; const nameSpan = document.createElement("span"); nameSpan.className = "role-name"; nameSpan.textContent = roleItem.textContent?.trim() || ""; container.appendChild(nameSpan); roleItem.textContent = ""; roleItem.appendChild(container); } const roleName = roleItem.textContent?.trim(); console.log("Role name from textContent:", roleName); const roleNameAlt = container.querySelector(".role-name")?.textContent; console.log("Role name from span:", roleNameAlt); if (!container.querySelector(".folder-icon")) { const folderButton = document.createElement("span"); folderButton.innerHTML = "📁"; folderButton.className = "folder-icon"; folderButton.addEventListener("click", (event) => { event.stopPropagation(); console.log("Clicked role name:", roleName); console.log("Available roles:", group.roles.map((r) => r.name)); const role = group.roles.find((r) => r.name === roleName); if (role) { console.log("Found role:", role); this.showRoleDocuments(role, group); } else { console.error("Role not found. Name:", roleName); console.error("Available roles:", group.roles); } }); container.appendChild(folderButton); } }); roleList.style.display = roleList.style.display === "none" ? "block" : "none"; } } loadGroupList() { const groupList = this.shadowRoot?.getElementById("group-list"); if (!groupList) return; groupsMock.forEach((group) => { const li = document.createElement("li"); li.className = "group-list-item"; const container = document.createElement("div"); container.className = "group-item-container"; const nameSpan = document.createElement("span"); nameSpan.textContent = group.name; nameSpan.className = "process-name"; nameSpan.addEventListener("click", (event) => { event.stopPropagation(); this.toggleRoles(group, li); }); const settingsIcon = document.createElement("span"); settingsIcon.textContent = "⚙️"; settingsIcon.className = "settings-icon"; settingsIcon.id = `settings-${group.id}`; settingsIcon.onclick = (event) => { event.stopPropagation(); this.showProcessDetails(group, group.id); }; container.appendChild(nameSpan); container.appendChild(settingsIcon); li.appendChild(container); const roleList = document.createElement("ul"); roleList.className = "role-list"; roleList.style.display = "none"; group.roles.forEach((role) => { const roleItem = document.createElement("li"); roleItem.className = "role-item"; roleItem.textContent = role.name; roleItem.onclick = (event) => { event.stopPropagation(); this.toggleMembers(role, roleItem); }; roleList.appendChild(roleItem); }); li.appendChild(roleList); groupList.appendChild(li); }); } // Function to manage the list of users toggleUserList() { const userList = getCorrectDOM("userList"); if (!userList) return; if (!userList.classList.contains("show")) { userList.innerHTML = membersMock.map((member) => `
${member.avatar}
${member.name} ${member.email}
`).join(""); } userList.classList.toggle("show"); } switchUser(userId) { const user = membersMock.find((member) => member.id === userId); if (!user) return; currentUser = user; this.updateCurrentUserDisplay(); const userList = getCorrectDOM("userList"); userList?.classList.remove("show"); } // Function to update the display of the current user updateCurrentUserDisplay() { const userDisplay = getCorrectDOM("current-user"); if (userDisplay) { userDisplay.innerHTML = `
${currentUser.avatar} ${currentUser.name}
`; } } // Generate an automatic response generateAutoReply(senderName) { return { id: Date.now(), sender: senderName, text: "OK...", time: (/* @__PURE__ */ new Date()).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }), type: "text" }; } // Send a file sendFile(file) { console.log("SendFile called with file:", file); const reader = new FileReader(); reader.onloadend = () => { const fileData = reader.result; const fileName = file.name; console.log("File loaded:", fileName); if (this.selectedMemberId) { messageStore.addMessage(this.selectedMemberId, { id: Date.now(), sender: "4NK", fileName, fileData, time: (/* @__PURE__ */ new Date()).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }), type: "file" }); console.log("Message added to store"); this.messagesMock = messageStore.getMessages(); this.loadMemberChat(this.selectedMemberId); } }; reader.readAsDataURL(file); } // Managing the sent file fileList = this.shadowRoot?.getElementById("fileList"); getFileList() { const files = Array.from(this.fileList?.querySelectorAll(".file-item") || []).map((fileItem) => { const fileName = fileItem.querySelector(".file-name")?.textContent || ""; return { name: fileName, url: fileItem.dataset.content || "#" }; }); return files; } // New function to display the documents of a role showRoleDocuments(role, group) { const storedGroups = JSON.parse(localStorage.getItem("groups") || "[]"); const storedGroup = storedGroups.find((g) => g.id === group.id); const storedRole = storedGroup?.roles.find((r) => r.name === role.name); const displayRole = storedRole || role; console.log("Showing documents for role:", displayRole.name, "in group:", group.name); const allDetailsAreas = this.shadowRoot?.querySelectorAll(".process-details"); allDetailsAreas?.forEach((area) => { area.remove(); }); const container = this.shadowRoot?.querySelector(".container"); if (!container) { console.error("Container not found"); return; } const detailsArea = document.createElement("div"); detailsArea.id = `role-documents-${displayRole.name}`; detailsArea.className = "process-details"; const accessibleDocuments = (displayRole.documents || []).filter((doc) => this.canUserAccessDocument(doc, displayRole.name, currentUser.processRoles?.[0]?.role || "")); detailsArea.innerHTML = ` `; container.appendChild(detailsArea); } // Function to close the documents view of a role closeRoleDocuments(roleName) { const detailsArea = this.shadowRoot?.getElementById(`role-documents-${roleName}`); if (detailsArea) { detailsArea.remove(); } } handleFiles(files, fileList) { Array.from(files).forEach((file) => { const reader = new FileReader(); reader.onload = (e) => { const fileContent = e.target?.result; const existingFiles = fileList.querySelectorAll(".file-name"); const isDuplicate = Array.from(existingFiles).some((existingFile) => existingFile.textContent === file.name); if (!isDuplicate) { const fileItem = document.createElement("div"); fileItem.className = "file-item"; fileItem.innerHTML = `
${file.name} (${(file.size / 1024).toFixed(1)} KB)
`; fileItem.dataset.content = fileContent; const removeBtn = fileItem.querySelector(".remove-file"); if (removeBtn) { removeBtn.addEventListener("click", () => fileItem.remove()); } fileList.appendChild(fileItem); } }; reader.readAsDataURL(file); }); } // Function to manage the new request newRequest(params) { if (!params || !params.processId) { console.error("Paramètres invalides:", params); this.showAlert("Invalid parameters for new request"); return; } const modal = document.createElement("div"); modal.className = "modal-overlay"; const process = groupsMock.find((g) => g.id === params.processId); if (!process) { console.error("Processus non trouvé:", params.processId); this.showAlert("Process not found"); return; } let membersToDisplay = []; try { if (params.roleName === "common") { membersToDisplay = process.roles.reduce((members, role) => { return members.concat(role.members.map((member) => ({ ...member, roleName: role.name }))); }, []); } else { const role = process.roles.find((r) => r.name === params.roleName); if (!role) { throw new Error(`Role ${params.roleName} not found`); } membersToDisplay = role.members.map((member) => ({ ...member, roleName: params.roleName })); } } catch (error) { console.error("Error retrieving members:", error); this.showAlert("Error retrieving members"); return; } modal.innerHTML = ` `; this.shadowRoot?.appendChild(modal); const dropZone = modal.querySelector("#dropZone"); const fileInput = modal.querySelector("#fileInput"); const fileList = modal.querySelector("#fileList"); dropZone.addEventListener("click", () => { fileInput.click(); }); fileInput.addEventListener("change", (e) => { const target = e.target; if (target.files && target.files.length > 0) { this.handleFiles(target.files, fileList); } }); dropZone.addEventListener("dragover", (e) => { e.preventDefault(); dropZone.classList.add("dragover"); }); dropZone.addEventListener("dragleave", () => { dropZone.classList.remove("dragover"); }); dropZone.addEventListener("drop", (e) => { e.preventDefault(); dropZone.classList.remove("dragover"); if (e.dataTransfer?.files) { this.handleFiles(e.dataTransfer.files, fileList); } }); } closeModal(button) { const modalOverlay = button.closest(".modal-overlay"); if (modalOverlay) { modalOverlay.remove(); } } submitNewDocument(event) { event.preventDefault(); const form = this.shadowRoot?.getElementById("newDocumentForm"); if (!form) { this.showAlert("Form not found"); return; } const fileList = this.shadowRoot?.getElementById("fileList"); const files = Array.from(fileList?.querySelectorAll(".file-item") || []).map((fileItem) => { const fileName = fileItem.querySelector(".file-name")?.textContent || ""; return { name: fileName, url: fileItem.dataset.content || "#" }; }); const processId = Number(form.querySelector("#processId")?.value); const documentId = Number(form.querySelector("#documentId")?.value); const documentName = form.querySelector("#documentName")?.value?.trim(); const description = form.querySelector("#description")?.value?.trim(); const deadline = form.querySelector("#deadline")?.value; const visibility = form.querySelector("#visibility")?.value; if (!documentName || !description || !deadline) { this.showAlert("Please fill in all required fields"); return; } try { const groups = JSON.parse(localStorage.getItem("groups") || JSON.stringify(groupsMock)); const group = groups.find((g) => g.id === processId); if (!group) { this.showAlert("Process not found"); return; } const role = group.roles.find((r) => r.documents?.some((d) => d.id === documentId)); if (!role) { this.showAlert("Role not found"); return; } const updatedDocument = { id: documentId, name: documentName, description, createdAt: (/* @__PURE__ */ new Date()).toISOString(), deadline, visibility, status: "pending", signatures: role.members.map((member) => ({ member, signed: false, signedAt: null })), files // Ajout des fichiers au document }; const documentIndex = role.documents.findIndex((d) => d.id === documentId); if (documentIndex !== -1) { role.documents[documentIndex] = updatedDocument; } localStorage.setItem("groups", JSON.stringify(groups)); const mockGroup = groupsMock.find((g) => g.id === processId); if (mockGroup) { const mockRole = mockGroup?.roles.find((r) => r.name === role.name); if (mockRole?.documents) { const mockDocIndex = mockRole.documents.findIndex((d) => d.id === documentId); if (mockDocIndex !== -1) { mockRole.documents[mockDocIndex] = { ...updatedDocument, status: void 0 }; } } } if (event.target instanceof HTMLElement) { this.closeModal(event.target); } this.showRoleDocuments(role, group); this.showAlert("Document updated successfully!"); } catch (error) { console.error("Error saving:", error); this.showAlert("An error occurred while saving"); } } submitCommonDocument(event) { event.preventDefault(); const form = this.shadowRoot?.getElementById("newDocumentForm"); if (!form) { this.showAlert("Form not found"); return; } const processId = Number(form.querySelector("#processId")?.value); const documentId = Number(form.querySelector("#documentId")?.value); const documentName = form.querySelector("#documentName")?.value?.trim(); const description = form.querySelector("#description")?.value?.trim(); const deadline = form.querySelector("#deadline")?.value; const visibility = form.querySelector("#visibility")?.value; if (!documentName || !description || !deadline) { this.showAlert("Please fill in all required fields"); return; } try { const groups = JSON.parse(localStorage.getItem("groups") || JSON.stringify(groupsMock)); const group = groups.find((g) => g.id === processId); if (!group) { this.showAlert("Process not found"); return; } const allMembers = group.roles.reduce((acc, role) => { return acc.concat(role.members); }, []); const fileList = this.shadowRoot?.getElementById("fileList"); const files = Array.from(fileList?.querySelectorAll(".file-item") || []).map((fileItem) => { const fileName = fileItem.querySelector(".file-name")?.textContent || ""; return { name: fileName, url: fileItem.dataset.content || "#" }; }); const updatedDocument = { id: documentId, name: documentName, description, createdAt: (/* @__PURE__ */ new Date()).toISOString(), deadline, visibility, status: "pending", signatures: allMembers.map((member) => ({ member, signed: false, signedAt: null })), files }; const documentIndex = group.commonDocuments.findIndex((d) => d.id === documentId); if (documentIndex !== -1) { group.commonDocuments[documentIndex] = updatedDocument; } localStorage.setItem("groups", JSON.stringify(groups)); if (event.target instanceof HTMLElement) { this.closeModal(event.target); } this.showProcessDetails(group, group.id); this.showAlert("Document common updated successfully!"); } catch (error) { console.error("Error saving:", error); this.showAlert("An error occurred while saving"); } } submitRequest() { this.showAlert("Request submitted!"); } closeNewRequest() { const newRequestView = document.getElementById("new-request-view"); if (newRequestView) { newRequestView.style.display = "none"; newRequestView.remove(); } } submitDocumentRequest(documentId) { const createdAt = this.shadowRoot?.getElementById("createdAt")?.value || ""; const deadline = this.shadowRoot?.getElementById("deadline")?.value || ""; const visibility = this.shadowRoot?.getElementById("visibility")?.value || ""; const description = this.shadowRoot?.getElementById("description")?.value || ""; const selectedMembers = Array.from(this.shadowRoot?.querySelectorAll('input[name="selected-members"]:checked') || []).map((checkbox) => checkbox.value); if (!createdAt || !deadline || selectedMembers.length === 0) { this.showAlert("Please fill in all required fields and select at least one member."); return; } console.log("Document submission:", { documentId, createdAt, deadline, visibility, description, selectedMembers }); this.showAlert("Document request submitted successfully!"); this.closeNewRequest(); } // FUNCTIONS FOR SIGNATURE // New function to confirm the signature confirmSignature(documentId, processId, isCommonDocument) { try { console.log("Current user:", currentUser); const groups = JSON.parse(localStorage.getItem("groups") || JSON.stringify(groupsMock)); const group = groups.find((g) => g.id === processId); if (!group) { throw new Error("Process not found"); } let targetDoc; if (isCommonDocument) { targetDoc = group.commonDocuments.find((d) => d.id === documentId); } else { for (const role of group.roles) { if (role.documents) { targetDoc = role.documents.find((d) => d.id === documentId); if (targetDoc) break; } } } if (!targetDoc) { throw new Error("Document not found"); } const userSignature = targetDoc.signatures.find((sig) => sig.member.name === currentUser.name); if (!userSignature) { throw new Error(`The user ${currentUser.name} is not authorized to sign this document. Please log in with an authorized user.`); } userSignature.signed = true; userSignature.signedAt = (/* @__PURE__ */ new Date()).toISOString(); localStorage.setItem("groups", JSON.stringify(groups)); const modalOverlay = this.shadowRoot?.querySelector(".modal-overlay"); if (modalOverlay) { modalOverlay.remove(); } if (isCommonDocument) { this.showProcessDetails(group, processId); } else { const role = group.roles.find((r) => r.documents?.includes(targetDoc)); if (role) { this.showRoleDocuments(role, group); } } this.showAlert("Document signed successfully!"); } catch (error) { console.error("Error signing document:", error); this.showAlert(error instanceof Error ? error.message : "Error signing document"); } } initializeEventListeners() { document.addEventListener("DOMContentLoaded", () => { const newRequestBtn = this.shadowRoot?.getElementById("newRequestBtn"); if (newRequestBtn) { newRequestBtn.addEventListener("click", () => { this.newRequest({ processId: 0, processName: "", roleId: 0, roleName: "", documentId: 0, documentName: "" }); }); } }); const sendBtn = this.shadowRoot?.querySelector("#send-button"); if (sendBtn) { sendBtn.addEventListener("click", this.sendMessage.bind(this)); } const messageInput = this.shadowRoot?.querySelector("#message-input"); if (messageInput) { messageInput.addEventListener("keypress", (event) => { if (event.key === "Enter") { event.preventDefault(); this.sendMessage(); } }); } const fileInput = this.shadowRoot?.querySelector("#file-input"); if (fileInput) { fileInput.addEventListener("change", (event) => { const file = event.target.files?.[0]; if (file) { this.sendFile(file); } }); } } connectedCallback() { this.messagesMock = messageStore.getMessages(); if (this.messagesMock.length === 0) { messageStore.setMessages(messagesMock); this.messagesMock = messageStore.getMessages(); } this.updateCurrentUserDisplay(); this.initializeEventListeners(); this.loadGroupList(); } } customElements.define("signature-element", SignatureElement); const signatureCss = "/* Styles de base */\n:root {\n --primary-color: #3A506B;\n /* Bleu métallique */\n --secondary-color: #B0BEC5;\n /* Gris acier */\n --accent-color: #D68C45;\n /* Cuivre */\n}\n\nbody {\n font-family: Arial, sans-serif;\n margin: 0;\n padding: 0;\n display: flex;\n height: 100vh;\n background-color: #e9edf1;\n flex-direction: column;\n}\n\n\n\n/* 4NK NAVBAR */\n\n.brand-logo {\n text-align: center;\n font-size: 1.5em;\n font-weight: bold;\n}\n\n.nav-wrapper {\n position: fixed;\n background: radial-gradient(circle, white, var(--primary-color));\n display: flex;\n justify-content: space-between;\n align-items: center;\n color: #37474F;\n height: 9vh;\n width: 100vw;\n left: 0;\n top: 0;\n box-shadow: 0px 8px 10px -5px rgba(0, 0, 0, .2), 0px 16px 24px 2px rgba(0, 0, 0, .14), 0px 6px 30px 5px rgba(0, 0, 0, .12);\n}\n\n/* Icônes de la barre de navigation */\n.nav-right-icons {\n display: flex;\n}\n\n.notification-bell,\n.burger-menu {\n height: 20px;\n width: 20px;\n margin-right: 1rem;\n cursor: pointer;\n}\n\n.notification-container {\n position: relative;\n /* Conserve la position pour le notification-board */\n display: inline-flex;\n align-items: center;\n}\n\n.notification-board {\n position: absolute;\n /* Position absolue pour le placer par rapport au container */\n top: 40px;\n right: 0;\n background-color: white;\n border: 1px solid #ccc;\n padding: 10px;\n width: 200px;\n max-height: 300px;\n overflow-y: auto;\n /* Scroll si les notifications dépassent la taille */\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n z-index: 10;\n /* Définit la priorité d'affichage au-dessus des autres éléments */\n display: none;\n /* Par défaut, la notification est masquée */\n}\n\n.notification-item{\n cursor: pointer;\n}\n\n.notification-badge {\n position: absolute;\n top: -18px;\n right: 35px;\n background-color: red;\n color: white;\n border-radius: 50%;\n padding: 4px 8px;\n font-size: 12px;\n display: none;\n /* S'affiche seulement lorsqu'il y a des notifications */\n z-index: 10;\n}\n\n/* Par défaut, le menu est masqué */\n#menu {\n display: none;\n /* Menu caché par défaut */\n transition: display 0.3s ease-in-out;\n}\n\n.burger-menu {\n cursor: pointer;\n}\n\n/* Icône burger */\n#burger-icon {\n cursor: pointer;\n}\n\n.menu-content {\n display: none;\n position: absolute;\n top: 3.4rem;\n right: 1rem;\n background-color: white;\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n border-radius: 5px;\n overflow: hidden;\n}\n\n.menu-content a {\n display: block;\n padding: 10px 20px;\n text-decoration: none;\n color: #333;\n border-bottom: 1px solid #e0e0e0;\n\n &:hover {\n background-color: rgba(26, 28, 24, .08);\n }\n}\n\n.menu-content a:last-child {\n border-bottom: none;\n}\n\n/* Ajustement pour la barre de navigation fixe */\n.container {\n display: flex;\n flex: 1;\n height: 90vh;\n margin-top: 9vh;\n margin-left: -1%;\n text-align: left;\n width: 209vh;\n}\n\n\n/* Liste des groupes */\n\n.group-list {\n width: 25%;\n background-color: #1f2c3d;\n color: white;\n padding: 20px;\n box-sizing: border-box;\n overflow-y: auto;\n border-right: 2px solid #2c3e50;\n flex-shrink: 0;\n padding-right: 10px;\n height: 91vh;\n}\n\n.group-list ul {\n cursor: pointer;\n list-style: none;\n padding: 0;\n padding-right: 10px;\n margin-left: 20px;\n}\n\n.group-list li {\n margin-bottom: 10px;\n padding: 15px;\n border-radius: 8px;\n background-color: #273646;\n cursor: pointer;\n transition: background-color 0.3s, box-shadow 0.3s;\n}\n\n.group-list li:hover {\n background-color: #34495e;\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);\n}\n\n\n/* Zone de chat */\n\n.chat-area {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n background-color: #ffffff;\n border-radius: 10px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);\n margin: 0px;\n margin-top: 20px;\n margin-left: 1%;\n margin-bottom: -7px;\n}\n\n/* En-tête du chat */\n.chat-header {\n background-color: #34495e;\n color: white;\n padding: 15px;\n font-size: 20px;\n font-weight: bold;\n border-radius: 10px 10px 0 0;\n text-align: center;\n}\n\n/* Messages */\n.messages {\n flex: 1;\n padding: 20px;\n overflow-y: auto;\n background-color: #f1f1f1;\n border-top: 1px solid #ddd;\n}\n\n.message-container {\n max-width: 100%;\n border-radius: 5px;\n overflow-wrap: break-word;\n word-wrap: break-word;\n background-color: #f1f1f1;\n display: flex; \n flex-direction: column; \n}\n\n.message-container .message {\n align-self: flex-start; \n}\n\n.message-container .message.user {\n align-self: flex-end; \n margin-left: auto; \n color: white;\n}\n\n.message {\n padding: 12px 18px;\n background-color: #e1e1e1;\n border-radius: 15px;\n max-width: 70%;\n font-size: 16px;\n line-height: 1.4;\n margin-bottom: 0%;\n white-space: pre-wrap;\n word-wrap: break-word;\n position: relative;\n display: inline-block;\n}\n\n/* Messages de l'utilisateur */\n.message.user {\n background-color: #3498db;\n color: white;\n align-self: flex-end;\n text-align: right;\n}\n\n/* Amélioration de l'esthétique des messages */\n/* .message.user:before {\n content: '';\n position: absolute;\n top: 10px;\n right: -10px;\n border: 10px solid transparent;\n border-left-color: #3498db;\n} */\n\n/* Zone de saisie */\n.input-area {\n padding: 10px;\n background-color: #bdc3c7;\n display: flex;\n align-items: center;\n /* Alignement vertical */\n}\n\n.input-area input[type=\"text\"] {\n flex: 1;\n /* Prend l'espace restant */\n padding: 10px;\n border: 1px solid #ccc;\n border-radius: 5px;\n}\n\n.input-area .attachment-icon {\n margin: 0 10px;\n cursor: pointer;\n display: flex;\n align-items: center;\n}\n\n.input-area button {\n padding: 10px;\n margin-left: 10px;\n background-color: #2980b9;\n color: white;\n border: none;\n border-radius: 5px;\n cursor: pointer;\n}\n\n.input-area button:hover {\n background-color: #1f608d;\n}\n\n#message-input {\n width: 100%;\n height: 50px;\n resize: none;\n padding: 10px;\n box-sizing: border-box;\n overflow: auto;\n max-width: 100%;\n border-radius: 10px;\n}\n\n/* Responsive */\n@media screen and (max-width: 768px) {\n .group-list {\n display: none;\n /* Masquer la liste des groupes sur les petits écrans */\n }\n\n .chat-area {\n margin: 0;\n }\n}\n\n#process-details {\n flex: 1;\n background: white;\n border-radius: 8px;\n margin: 10px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n display: none;\n overflow: hidden;\n}\n\n.process-details-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 20px;\n background: #f8f9fa;\n border-bottom: 1px solid #eee;\n border-radius: 8px 8px 0 0;\n}\n\n.process-details-header h2 {\n margin: 0;\n color: #333;\n}\n\n.close-btn {\n background: none;\n border: none;\n font-size: 24px;\n cursor: pointer;\n color: #666;\n}\n\n.close-btn:hover {\n color: #333;\n}\n\n.process-details-content {\n padding: 20px;\n overflow-y: auto;\n height: calc(100% - 70px);\n}\n\n.details-section {\n margin-bottom: 30px;\n}\n\n.details-section h3 {\n color: #444;\n margin-bottom: 15px;\n padding-bottom: 8px;\n border-bottom: 2px solid #f0f0f0;\n}\n\n.documents-list {\n list-style: none;\n padding: 0;\n}\n\n.documents-list li {\n padding: 8px 0;\n border-bottom: 1px solid #eee;\n}\n\n.roles-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n gap: 20px;\n}\n\n.role-block {\n background: #f8f9fa;\n border-radius: 8px;\n padding: 15px;\n border: 1px solid #eee;\n}\n\n.role-block h4 {\n color: #555;\n margin: 0 0 10px 0;\n padding-bottom: 8px;\n border-bottom: 1px solid #eee;\n}\n\n.members-list {\n list-style: none;\n padding: 0;\n}\n\n.members-list li {\n padding: 8px 12px;\n margin: 4px 0;\n cursor: pointer;\n border-radius: 4px;\n transition: background-color 0.2s;\n}\n\n.members-list li:hover {\n background-color: #e9ecef;\n}\n\n.group-list-item {\n padding: 8px 16px;\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n}\n\n.group-item-container {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n}\n\n.process-name {\n flex-grow: 1;\n cursor: pointer;\n}\n\n.settings-icon {\n cursor: pointer;\n padding: 5px 8px;\n margin-left: 10px;\n border-radius: 4px;\n}\n\n.settings-icon:hover {\n background-color: rgba(255, 255, 255, 0.1);\n}\n\n.process-details {\n position: fixed;\n top: 9vh;\n right: 0;\n bottom: 0;\n left: 23.5%;\n background-color: white;\n box-sizing: border-box;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n border-radius: 8px;\n margin: 10px;\n z-index: 990;\n}\n\n.process-details-content {\n height: calc(100% - 60px); /* Ajusté pour tenir compte du header */\n overflow-y: auto;\n padding: 20px;\n}\n\n.documents-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 20px;\n margin-top: 15px;\n}\n\n.document-card {\n background: white;\n border-radius: 8px;\n padding: 15px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n border: 1px solid #eee;\n}\n\n.document-card.public {\n border-left: 4px solid #4CAF50;\n}\n\n.document-card.private {\n border-left: 4px solid #FFC107;\n}\n\n.document-card.confidential {\n border-left: 4px solid #F44336;\n}\n\n.document-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 10px;\n padding-bottom: 10px;\n border-bottom: 1px solid #eee;\n}\n\n.document-header h4 {\n margin: 0;\n color: #333;\n}\n\n.document-visibility {\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 12px;\n font-weight: bold;\n}\n\n.public .document-visibility {\n background-color: #E8F5E9;\n color: #2E7D32;\n}\n\n.private .document-visibility {\n background-color: #FFF3E0;\n color: #F57C00;\n}\n\n.confidential .document-visibility {\n background-color: #FFEBEE;\n color: #C62828;\n}\n\n.document-info {\n margin: 10px 0;\n font-size: 14px;\n color: #666;\n}\n\n.document-info p {\n margin: 5px 0;\n}\n\n.signatures-list {\n margin-top: 10px;\n}\n\n.signature-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px;\n border-radius: 4px;\n margin: 5px 0;\n background-color: #f8f9fa;\n}\n\n.signature-item.signed {\n background-color: #E8F5E9;\n}\n\n.signature-item.pending {\n background-color: #FFF3E0;\n}\n\n.signer-name {\n font-weight: 500;\n}\n\n.signature-status {\n font-size: 12px;\n}\n\n.signed .signature-status {\n color: #2E7D32;\n}\n\n.pending .signature-status {\n color: #F57C00;\n}\n\n.user-selector {\n position: relative;\n margin-right: 20px;\n}\n\n#userSwitchBtn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 8px 12px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n color: var(--primary-color);\n}\n\n#userSwitchBtn:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.current-user-info {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.user-avatar {\n background-color: var(--primary-color);\n color: white;\n width: 32px;\n height: 32px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: bold;\n}\n\n.user-list {\n position: absolute;\n top: 100%;\n right: 0;\n background: white;\n border-radius: 4px;\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n display: none;\n z-index: 1000;\n max-height: 400px;\n overflow-y: auto;\n width: 250px;\n}\n\n.user-list.show {\n display: block;\n}\n\n.user-list-item {\n padding: 8px 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n}\n\n.user-list-item:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.user-list-item .user-avatar {\n width: 24px;\n height: 24px;\n font-size: 12px;\n}\n\n.user-list-item .user-email {\n font-size: 12px;\n color: #666;\n display: block;\n}\n\n.document-card {\n margin-bottom: 20px;\n padding: 10px;\n border: 1px solid #ccc;\n border-radius: 5px;\n}\n\n.progress-bar {\n background-color: #f3f3f3;\n border-radius: 5px;\n height: 10px;\n width: 100%;\n margin-top: 5px;\n}\n\n.progress {\n background-color: #4caf50; /* Couleur de la barre de progression */\n height: 100%;\n border-radius: 5px;\n}\n\n.new-request-btn {\n background-color: #4caf50; \n color: white; \n border: none;\n border-radius: 5px; \n padding: 10px 15px; \n cursor: pointer; \n margin-left: 10px;\n}\n\n.new-request-btn:hover {\n background-color: #45a049; \n}\n\n.header-buttons {\n display: flex;\n align-items: center; \n gap: 10px; \n}\n\n.close-btn {\n background: none;\n border: none;\n font-size: 24px;\n cursor: pointer;\n color: #666;\n}\n\n.close-btn:hover {\n color: #333;\n}\n\n.new-request-view {\n padding: 20px;\n background-color: white;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n margin: 20px;\n}\n\n.upload-area {\n border: 2px dashed #ccc;\n padding: 20px;\n text-align: center;\n margin: 20px 0;\n}\n\n.upload-icon {\n font-size: 50px;\n margin: 10px 0;\n}\n\n/* New Request View */\n.new-request-view {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: white;\n z-index: 1000; \n padding: 20px;\n box-sizing: border-box;\n overflow-y: auto;\n}\n\n.upload-area {\n border: 2px dashed #ccc;\n padding: 40px;\n text-align: center;\n margin: 20px auto;\n max-width: 600px;\n background-color: #f9f9f9;\n border-radius: 8px;\n cursor: pointer;\n}\n\n.upload-icon {\n font-size: 50px;\n margin: 20px 0;\n}\n\n.new-request-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-top: 60px;\n padding: 0 20px;\n}\n\n.upload-area {\n border: 2px dashed #ccc;\n padding: 40px;\n text-align: center;\n margin: 20px auto;\n max-width: 600px;\n background-color: #f9f9f9;\n border-radius: 8px;\n cursor: pointer;\n}\n\n.details-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n background-color: #f8f9fa;\n padding: 5px 20px;\n border-radius:20px;\n}\n\n.header-buttons {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-direction: row; \n}\n\n.close-btn {\n background: none;\n border: none;\n font-size: 24px;\n cursor: pointer;\n color: #666;\n padding: 5px;\n}\n\n.close-btn:hover {\n color: #333;\n}\n\n.new-request-btn {\n background-color: #4caf50;\n color: white;\n border: none;\n border-radius: 5px;\n padding: 8px 16px;\n cursor: pointer;\n /* margin-left: 10px; <- Supprimez cette ligne si elle existe */\n}\n\n.new-request-btn:hover {\n background-color: #45a049;\n}\n\n/* Ajoutez ces styles à votre fichier CSS existant */\n.document-card.vierge {\n background-color: #fff3cd;\n border: 2px solid #ffeeba;\n}\n\n.document-card.vierge .document-header {\n background-color: #fff3cd;\n}\n\n.document-card.vierge h4 {\n color: #856404;\n}\n\n.document-card.vierge .document-info {\n color: #856404;\n}\n\n/* Style pour l'emoji d'avertissement */\n.document-card.vierge h4::before {\n margin-right: 8px;\n}\n\n.vierge-documents-container {\n padding: 20px;\n overflow-y: auto;\n max-height: calc(100vh - 150px);\n}\n\n.document-form {\n padding: 15px;\n background-color: #fff;\n border-radius: 0 0 5px 5px;\n display: flex;\n gap: 20px;\n}\n\n.form-left {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 15px;\n}\n\n.form-right {\n display: flex;\n flex-direction: column;\n align-items: flex-end; /* Aligner le bouton à droite */\n}\n\n.form-group {\n flex: 2;\n display: flex;\n flex-direction: column;\n margin-bottom: 15px;\n}\n\n.form-group-members {\n flex: 2;\n display: flex;\n flex-direction: column;\n margin-bottom: 15px;\n font-weight: bold;\n}\n\n.submit-btn {\n background-color: #4caf50; \n color: white; \n border: none;\n border-radius: 5px; \n padding: 10px 15px; \n cursor: pointer; \n margin-left: 47%;\n margin-top: 20px;\n}\n\n.submit-btn:hover {\n background-color: #45a049;\n}\n\n.upload-format {\n font-size: 12px;\n color: #666;\n margin: 5px 0;\n}\n\n.browse-btn {\n background-color: #4caf50;\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: 4px;\n cursor: pointer;\n margin-top: 10px;\n}\n\n.browse-btn:hover {\n background-color: #45a049;\n}\n\n.document-selector {\n padding: 20px;\n margin-bottom: 20px;\n}\n\n.document-selector label {\n display: block;\n margin-bottom: 10px;\n font-weight: bold;\n color: #666;\n}\n\n.document-selector select {\n width: 100%;\n padding: 10px;\n border: 1px solid #ddd;\n border-radius: 4px;\n font-size: 16px;\n background-color: white;\n}\n\n#selected-document-form {\n padding: 0 20px;\n overflow: auto;\n height: 65%;\n}\n\n/* Style pour l'option avec l'emoji */\n.document-selector select option {\n padding: 10px;\n font-size: 14px;\n}\n\n.members-selection {\n max-height: 200px;\n overflow-y: auto;\n border: 1px solid #ddd;\n border-radius: 4px;\n padding: 10px;\n background-color: white;\n}\n\n.member-checkbox {\n display: flex;\n align-items: center;\n margin-bottom: 8px;\n padding: 5px;\n}\n\n.member-checkbox:hover {\n background-color: #f5f5f5;\n}\n\n.member-checkbox input[type=\"checkbox\"] {\n margin-right: 10px;\n}\n\n.member-checkbox label {\n cursor: pointer;\n flex: 1;\n}\n\n/* Style pour le conteneur des membres */\n.members-selection-container {\n display: flex;\n flex-direction: column;\n align-items: center; /* Centrer la liste des membres */\n width: 100%;\n}\n\n#members-list {\n width: 60%;\n height: 100%;\n margin-bottom: -40px;\n margin-top: 10px;\n}\n\n/* Style pour le label des membres */\n.members-selection-container label {\n font-weight: bold; /* Mettre le texte en gras */\n margin-bottom: 10px; /* Espacement en bas */\n display: block; /* Affichage en bloc */\n}\n\n/* Style pour les cases à cocher des membres */\n.member-checkbox {\n display: flex;\n align-items: center;\n margin-bottom: 8px;\n padding: 5px;\n border-radius: 4px; /* Coins arrondis */\n transition: background-color 0.2s; /* Transition pour l'effet de survol */\n}\n\n.member-checkbox:hover {\n background-color: #e9ecef; /* Couleur de fond au survol */\n}\n\n/* Style pour les labels */\n.form-group label {\n font-weight: bold; \n margin-bottom: 5px; \n}\n\n/* Style pour les champs de saisie */\n.form-group input,\n.form-group select {\n padding: 10px;\n border: 1px solid #ddd;\n border-radius: 4px;\n font-size: 16px;\n width: 80%;\n}\n\n.add-members-btn {\n background-color: #4caf50; \n color: white; \n border: none; \n border-radius: 5px; \n padding: 10px 15px; \n cursor: pointer; \n margin-top: 10px; /* Espacement au-dessus du bouton */\n}\n\n.add-members-btn:hover {\n background-color: #45a049; \n}\n\n/* Styles pour l'overlay et la modale */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n z-index: 999;\n}\n\n.modal {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background-color: white;\n padding: 20px;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n z-index: 1000;\n width: 25%;\n max-width: 500px;\n}\n\n.modal-content {\n max-height: 70vh;\n overflow-y: auto;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n margin-top: 20px;\n padding-top: 10px;\n border-top: 1px solid #eee;\n}\n\n.confirm-btn {\n background-color: #4caf50;\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.confirm-btn:hover {\n background-color: #45a049;\n}\n\n.selected-member {\n display: flex;\n justify-content: space-between;\n align-items: center;\n background-color: #f5f5f5;\n padding: 8px 12px;\n margin: 4px 0;\n border-radius: 4px;\n}\n\n.cancel-btn {\n background-color: #df2020; \n color: white; \n border: none;\n padding: 8px 16px; \n border-radius: 4px; \n cursor: pointer;\n}\n\n.cancel-btn:hover {\n background-color: #c62828; /\n}\n\n.remove-member-btn {\n background-color: #dc3545;\n color: white;\n border: none;\n border-radius: 50%;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 16px;\n padding: 0;\n margin-left: 8px;\n}\n\n.remove-member-btn:hover {\n background-color: #c82333;\n}\n\n#description {\n height: 100px;\n width: 100%;\n border-radius: 20px;\n padding: 10px 0;\n padding-left: 10px;\n resize: none;\n\n}\n\n.role-item-container {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n padding: 5px 0;\n}\n\n.role-item-container span:last-child {\n margin-left: 10px;\n}\n\n.document-card .new-request-btn {\n margin-top: 60%;\n margin-left: 65%;\n padding: 6px 12px;\n background-color: #4CAF50;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 0.9em;\n}\n\n.document-card .new-request-btn:hover {\n background-color: #45a049;\n}\n\n/* Styles pour la modale de nouveau document */\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n}\n\n\n.modal-content-document {\n background: white;\n padding: 20px;\n border-radius: 8px;\n width: 97%;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n padding-bottom: 10px;\n border-bottom: 1px solid #eee;\n}\n\n.modal-header h2 {\n margin: 0;\n color: #333;\n}\n\n.modal-body {\n margin-bottom: 20px;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n padding-top: 20px;\n border-top: 1px solid #eee;\n}\n\n.modal-document {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n}\n.form-group {\n margin-bottom: 15px;\n}\n\n.form-group label {\n display: block;\n margin-bottom: 5px;\n font-weight: bold;\n color: #555;\n}\n\n.form-control {\n width: 100%;\n padding: 8px;\n border: 1px solid #ddd;\n border-radius: 4px;\n font-size: 14px;\n}\n\n.form-row {\n display: flex;\n gap: 15px;\n margin-bottom: 15px;\n}\n\n.form-group.half {\n flex: 1;\n margin-bottom: 0; /* Annule la marge du form-group standard */\n}\n\n.selected-signatories {\n margin: 10px 0;\n padding: 10px;\n border: 1px solid #ddd;\n border-radius: 4px;\n min-height: 50px;\n}\n\n.signatory-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 5px;\n margin: 5px 0;\n background: #f5f5f5;\n border-radius: 4px;\n}\n\n.remove-btn {\n background: none;\n border: none;\n color: #dc3545;\n cursor: pointer;\n font-size: 18px;\n padding: 0 5px;\n}\n\n.remove-btn:hover {\n color: #bd2130;\n}\n\n.btn-primary {\n background: #4CAF50;\n color: white;\n padding: 10px 20px;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.btn-primary:hover {\n background: #45a049;\n}\n\n.btn-secondary {\n background: #6c757d;\n color: white;\n padding: 8px 15px;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.btn-secondary:hover {\n background: #5a6268;\n}\n\n.signatories-list {\n max-height: 300px;\n overflow-y: auto;\n}\n\n.signatory-option {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px;\n border-bottom: 1px solid #eee;\n}\n\n.role-select {\n padding: 4px;\n border: 1px solid #ddd;\n border-radius: 4px;\n margin-left: auto;\n}\n\n.role-section {\n margin-bottom: 20px;\n padding: 10px;\n background: #f8f9fa;\n border-radius: 4px;\n}\n\n.role-section h4 {\n margin: 0 0 10px 0;\n color: #495057;\n}\n\n.members-selection {\n max-height: 300px;\n overflow-y: auto;\n padding: 10px;\n border: 1px solid #dee2e6;\n border-radius: 4px;\n}\n\ninput[type=\"file\"] {\n padding: 10px;\n border: 1px dashed #ccc;\n border-radius: 4px;\n width: 100%;\n margin-top: 5px;\n}\n\n.file-upload-container {\n border: 2px dashed #ccc;\n padding: 20px;\n text-align: center;\n margin: 10px 0;\n border-radius: 5px;\n cursor: pointer;\n}\n\n.file-upload-container:hover {\n background-color: #f5f5f5;\n border-color: #666;\n}\n\n.file-upload-container.dragover {\n background-color: #f0f0f0;\n border-color: #4CAF50;\n}\n\n.file-list {\n margin-top: 10px;\n}\n\n.file-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px;\n margin: 5px 0;\n background: #f5f5f5;\n border-radius: 4px;\n}\n\n.file-info {\n display: flex;\n gap: 10px;\n align-items: center;\n}\n\n.remove-file {\n background: none;\n border: none;\n color: #ff4444;\n cursor: pointer;\n font-size: 18px;\n}\n\n#fileInput {\n display: none;\n}\n\n.required-signatories {\n margin: 10px 0;\n}\n\n.signatory-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px;\n margin: 5px 0;\n background: #f5f5f5;\n border-radius: 4px;\n}\n\n.signatory-item.locked {\n background: #e8e8e8;\n cursor: not-allowed;\n}\n\n.member-name {\n font-weight: 500;\n}\n\n.role-info {\n color: #666;\n font-size: 0.9em;\n}\n\n.lock-icon {\n margin-left: auto;\n opacity: 0.6;\n}\n\n/* Style pour la popup d'alerte */\n.alert-popup {\n position: fixed;\n top: 20px;\n left: 50%;\n transform: translateX(-50%);\n background-color: #f44336;\n color: white;\n padding: 15px 25px;\n border-radius: 4px;\n box-shadow: 0 2px 5px rgba(0,0,0,0.2);\n z-index: 1000;\n display: none;\n animation: slideDown 0.3s ease-out;\n}\n\n.sign-button {\n background-color: #4CAF50;\n color: white;\n padding: 8px 16px;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n margin-top: 10px;\n}\n\n.sign-button:hover {\n background-color: #45a049;\n}\n\n.sign-button:disabled {\n background-color: #cccccc;\n cursor: not-allowed;\n}\n\n.modal-document {\n background: white;\n border-radius: 8px;\n max-width: 800px;\n width: 90%;\n max-height: 95vh;\n overflow-y: auto;\n position: relative;\n}\n\n.document-details {\n padding: 20px;\n}\n\n.info-section {\n margin: 20px 0;\n background: #f8f9fa;\n padding: 15px;\n border-radius: 6px;\n}\n\n.info-row {\n display: flex;\n justify-content: space-between;\n margin-bottom: 10px;\n}\n\n.label {\n font-weight: bold;\n color: #666;\n}\n\n.description-section {\n margin: 20px 0;\n}\n\n.signatures-section {\n margin: 20px 0;\n}\n\n.signature-item {\n display: flex;\n justify-content: space-between;\n padding: 8px;\n border-bottom: 1px solid #eee;\n}\n\n.signature-item.signed {\n background-color: #e8f5e9;\n}\n\n.signature-item.pending {\n background-color: #fff3e0;\n}\n\n.files-section {\n margin: 20px 0;\n}\n\n.file-item {\n display: flex;\n align-items: center;\n padding: 8px;\n background: #f8f9fa;\n margin-bottom: 5px;\n border-radius: 4px;\n}\n\n.file-icon {\n margin-right: 10px;\n}\n\n.download-link {\n margin-left: auto;\n}\n\n.confirmation-section {\n margin-top: 30px;\n text-align: center;\n}\n\n.warning-text {\n color: #f44336;\n margin-bottom: 15px;\n}\n\n.sign-confirm-btn {\n background-color: #4CAF50;\n color: white;\n padding: 10px 20px;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.sign-confirm-btn:hover {\n background-color: #45a049;\n}\n\n.signature-slider-container {\n margin: 20px 20%;\n padding: 10px;\n}\n\n.slider-track {\n position: relative;\n background: #e0e0e0;\n height: 40px;\n border-radius: 20px;\n display: flex;\n align-items: center;\n overflow: hidden;\n}\n\n.slider-handle {\n position: absolute;\n left: 0;\n width: 40px;\n height: 40px;\n background: #4CAF50;\n border-radius: 50%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n touch-action: none;\n z-index: 1;\n}\n\n.slider-arrow {\n color: white;\n font-size: 20px;\n}\n\n.slider-text {\n width: 100%;\n text-align: center;\n color: #666;\n user-select: none;\n}"; class SignatureComponent extends HTMLElement { _callback; signatureElement = null; constructor() { super(); console.log("INIT"); this.attachShadow({ mode: "open" }); this.signatureElement = this.shadowRoot?.querySelector("signature-element") || null; } connectedCallback() { console.log("CALLBACKs"); this.render(); this.fetchData(); if (!customElements.get("signature-element")) { customElements.define("signature-element", SignatureElement); } } async fetchData() { { const service = await Services.getInstance(); await service.getProcesses(); } } set callback(fn) { if (typeof fn === "function") { this._callback = fn; } else { console.error("Callback is not a function"); } } get callback() { return this._callback; } render() { if (this.shadowRoot) { const signatureElement = document.createElement("signature-element"); this.shadowRoot.innerHTML = ``; this.shadowRoot.appendChild(signatureElement); } } } customElements.define("signature-component", SignatureComponent); export { SignatureComponent };