// ECO-PANNEAU.FR - _react/clients/_clients_settings_privacy.jsx window.pano_ClientSettingsPrivacy = ({ myClientData, data, showToast, refreshData, setArchiveConfig, openLocalDialog, closeCurrentLayer, activeDialog, onClose }) => { const { useState } = React; // ZÉRO-DETTE : Utilisation de notre Hook abstrait ! const { isMounted, safeFetch } = window.pano_useSafeFetch(); const [isSaving, setIsSaving] = useState(false); const [confirmConfig, setConfirmConfig] = useState(null); const [arcToReveal, setArcToReveal] = useState(null); const [revealedPwdData, setRevealedPwdData] = useState(null); // 1. - Composants et Icônes const { DownloadIcon, Trash2Icon, EyeIcon, FileTextIcon, ArchiveIcon, ShieldAlertIcon, MailIcon, LoaderIcon } = window.pano_getIcons(); const { Button, ConfirmModal, PasswordPromptModal, Modal } = window.pano_getComponents(); const rgpdArchives = (data.archives || []).filter(a => a.type === 'RGPD'); // 2. - Actions métier const handleDeleteArchive = (arc) => { setConfirmConfig({ title: "Supprimer l'archive RGPD", message: "Êtes-vous sûr de vouloir supprimer définitivement cette archive ? Cette action est irréversible.", confirmText: "Oui, supprimer", isDestructive: true, onConfirm: async () => { // ZÉRO-DETTE : Dépilement de la confirmation via l'historique natif closeCurrentLayer(); const d = await safeFetch('archives/delete', { body: { filename: arc.filename }, setLoading: setIsSaving, successMessage: "Archive supprimée avec succès." }); if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit if (d && refreshData) refreshData(); } }); openLocalDialog('confirm_privacy'); }; // ZÉRO-TRUST : Tentative d'accès via le Sudo-Mode (Session de 60min) const handleRevealPassword = async (filename) => { setArcToReveal(filename); const d = await safeFetch('archives/reveal_password', { body: { filename }, setLoading: setIsSaving }); if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit if (d && d.data?.password) { // Le serveur a validé la session de confiance setRevealedPwdData(d.data.password); openLocalDialog('show_pwd'); } else { // Le serveur a refusé (session d'une heure expirée ou invalide) // On retombe en sécurité maximale : on exige le mot de passe. openLocalDialog('pwd_arc'); } }; // 3. - Rendu UI return ( ( )} >
{/* BLOC 1 : PORTABILITÉ DES DONNÉES */}

{DownloadIcon && } Portabilité des données (RGPD)

Conformément au RGPD, vous pouvez télécharger une archive `.zip` contenant l'intégralité de vos données personnelles, vos factures, ainsi que les informations de vos panneaux. Les documents stockés dans le coffre-fort légal y sont inclus.

{rgpdArchives.length > 0 && (

Vos archives générées

{rgpdArchives.map((arc, i) => (
{ArchiveIcon && }

Archive de vos données (RGPD)

Disponible jusqu'au {new Date(arc.expires_at * 1000).toLocaleString('fr-FR', {dateStyle: 'short', timeStyle: 'short'})}

))}
)}
{/* BLOC 2 : SUPPRESSION DU COMPTE */}

{ShieldAlertIcon && } Suppression du compte

La suppression de votre compte est irréversible. Toutes vos données personnelles, ainsi que vos panneaux en brouillon seront détruits de nos serveurs. Cependant, pour des raisons légales, les données liées à la facturation et aux panneaux publics passés ou actifs sont conservées le temps de leurs délais légaux respectifs.

{/* 4. - Modales contextuelles sécurisées sans boucle infinie */} {activeDialog === 'confirm_privacy' && confirmConfig && ConfirmModal && ( { setConfirmConfig(null); closeCurrentLayer(); }} /> )} {activeDialog === 'pwd_arc' && arcToReveal && PasswordPromptModal && ( { const d = await safeFetch('archives/reveal_password', { body: { filename: arcToReveal, password: pwd }, setLoading: setIsSaving }); if (!isMounted.current) return; // SÉCURITÉ : Coupe-circuit if (d) { setRevealedPwdData(d.data.password); openLocalDialog('show_pwd'); } }} onCancel={closeCurrentLayer} isSaving={isSaving} /> )} {activeDialog === 'show_pwd' && revealedPwdData && Modal && ( ( <> )} >

Voici le mot de passe unique permettant d'extraire cette archive :

{revealedPwdData}
)}
); }; /* EOF ========== [_react/clients/_clients_settings_privacy.jsx] */