Ajout des cgu

This commit is contained in:
2026-05-21 09:58:04 +02:00
parent 5efd4dcf35
commit 87c099433b
14 changed files with 802 additions and 32 deletions
+161
View File
@@ -0,0 +1,161 @@
// src/pages/CGU/CGU.jsx
// Conditions Générales d'Utilisation — page publique sans sidebar
import { useNavigate } from 'react-router-dom';
import { ArrowLeft } from 'lucide-react';
import Button from '../../components/common/Button';
import styles from './CGU.module.css';
export default function CGU() {
const navigate = useNavigate();
return (
<div className={styles.page}>
<div className={styles.container}>
<header className={styles.header}>
<span className={styles.logo} aria-label="Data Sentinel"> Data Sentinel</span>
<Button variant="link" onClick={() => navigate(-1)} aria-label="Retour à la page précédente">
<ArrowLeft size={14} />
Retour
</Button>
</header>
<main id="main-content">
<h1 className={styles.mainTitle}>Conditions Générales d'Utilisation</h1>
<p className={styles.subtitle}>Version 1.0 — en vigueur depuis le 1er janvier 2026</p>
<section className={styles.section} aria-labelledby="art1">
<h2 id="art1">Article 1 — Objet et champ d'application</h2>
<p>
Les présentes Conditions Générales d'Utilisation (ci-après « CGU ») régissent l'accès et
l'utilisation de la plateforme <strong>Data Sentinel</strong>, outil interne de monitoring
de la qualité des données développé par COYAUD Anthony pour le compte de <strong>XEFI SA</strong>
(ci-après « l'Éditeur »).
</p>
<p>
Data Sentinel est une application web à usage professionnel interne, accessible uniquement
aux collaborateurs habilités de XEFI et de ses filiales. Toute utilisation de la plateforme
implique l'acceptation pleine et entière des présentes CGU.
</p>
</section>
<section className={styles.section} aria-labelledby="art2">
<h2 id="art2">Article 2 — Accès au service</h2>
<p>
L'accès à Data Sentinel est réservé aux utilisateurs disposant d'un compte valide créé
par un administrateur système XEFI. L'authentification s'effectue via un identifiant et
un mot de passe fournis par l'entreprise.
</p>
<ul className={styles.list}>
<li>Chaque utilisateur est responsable de la confidentialité de ses identifiants.</li>
<li>Le partage de comptes est strictement interdit.</li>
<li>Tout accès non autorisé doit être signalé immédiatement au service informatique.</li>
<li>L'Éditeur se réserve le droit de suspendre tout accès en cas d'utilisation non conforme.</li>
</ul>
</section>
<section className={styles.section} aria-labelledby="art3">
<h2 id="art3">Article 3 Description du service</h2>
<p>Data Sentinel offre les fonctionnalités suivantes :</p>
<ul className={styles.list}>
<li><strong>Dashboard</strong> Vue d'ensemble des indicateurs clés de qualité des données (KPI).</li>
<li><strong>Monitoring</strong> — Suivi en temps réel des monitorings CRM, Sage et Infocentre.</li>
<li><strong>Vue consolidée</strong> — Agrégation des résultats par service et catégorie.</li>
<li><strong>Historique</strong> — Consultation et export des données historiques.</li>
<li><strong>Administration</strong> — Gestion des nomenclatures, utilisateurs et journaux.</li>
</ul>
</section>
<section className={styles.section} aria-labelledby="art4">
<h2 id="art4">Article 4 — Obligations de l'utilisateur</h2>
<p>L'utilisateur s'engage à :</p>
<ul className={styles.list}>
<li>Utiliser la plateforme exclusivement dans le cadre de ses missions professionnelles.</li>
<li>Ne pas tenter de contourner les mécanismes de sécurité (authentification, contrôle d'accès).</li>
<li>Ne pas extraire, reproduire ou diffuser les données sans autorisation.</li>
<li>Signaler tout dysfonctionnement ou anomalie de sécurité à l'équipe informatique.</li>
<li>Respecter les règles internes XEFI relatives à la sécurité des systèmes d'information.</li>
</ul>
</section>
<section className={styles.section} aria-labelledby="art5">
<h2 id="art5">Article 5 — Protection des données personnelles (RGPD)</h2>
<p>
Conformément au Règlement Général sur la Protection des Données (UE 2016/679), XEFI SA
traite les données personnelles des utilisateurs dans le strict respect de la réglementation.
</p>
<div className={styles.infoBox} role="note" aria-label="Informations RGPD">
<p><strong>Responsable du traitement :</strong> XEFI SA — 2507 Avenue de l'Europe, 69140 Rillieux-la-Pape</p>
<p><strong>Délégué à la Protection des Données (DPO) :</strong> dpo@xefi.fr</p>
<p><strong>Finalité :</strong> Authentification, traçabilité des actions, sécurité du système.</p>
<p><strong>Durée de conservation :</strong> 24 mois à compter de la dernière connexion.</p>
<p><strong>Droits :</strong> Accès, rectification, effacement, portabilité à exercer auprès de dpo@xefi.fr.</p>
</div>
</section>
<section className={styles.section} aria-labelledby="art6">
<h2 id="art6">Article 6 Accessibilité</h2>
<p>
XEFI s'engage à rendre Data Sentinel accessible conformément au Référentiel Général
d'Amélioration de l'Accessibilité (RGAA). L'application respecte les principes WCAG 2.1
niveau AA : perceptibilité, utilisabilité, compréhension et robustesse.
</p>
<ul className={styles.list}>
<li>Navigation clavier intégrale supportée.</li>
<li>Compatibilité avec les lecteurs d'écran (ARIA labels, landmarks, roles).</li>
<li>Contrastes de couleurs conformes aux exigences WCAG 2.1 AA (ratio 4.5:1 minimum).</li>
<li>Interface responsive adaptée aux écrans de 320px à 1920px.</li>
</ul>
<p>
Pour signaler un problème d'accessibilité : <strong>dpo@xefi.fr</strong>
</p>
</section>
<section className={styles.section} aria-labelledby="art7">
<h2 id="art7">Article 7 Disponibilité et maintenance</h2>
<p>
L'Éditeur s'efforce de maintenir la plateforme disponible 24h/24, 7j/7, sans garantie
de continuité de service. Des interruptions peuvent survenir pour maintenance planifiée
ou en cas d'incident technique. Les utilisateurs seront prévenus dans la mesure du possible.
</p>
</section>
<section className={styles.section} aria-labelledby="art8">
<h2 id="art8">Article 8 — Propriété intellectuelle</h2>
<p>
L'ensemble des éléments composant Data Sentinel (code source, design, données, documentation)
est la propriété exclusive de <strong>XEFI SA</strong>. Toute reproduction, modification
ou diffusion sans autorisation écrite préalable est interdite.
</p>
<p>Application développée par <strong>COYAUD Anthony</strong> Bachelor DBI, Nexa Digital School, 2026.</p>
</section>
<section className={styles.section} aria-labelledby="art9">
<h2 id="art9">Article 9 Modification des CGU</h2>
<p>
XEFI SA se réserve le droit de modifier les présentes CGU à tout moment. Les utilisateurs
seront informés de toute modification substantielle. La poursuite de l'utilisation de la
plateforme après notification vaut acceptation des nouvelles conditions.
</p>
</section>
<section className={styles.section} aria-labelledby="art10">
<h2 id="art10">Article 10 — Droit applicable et contact</h2>
<p>Les présentes CGU sont soumises au droit français. Pour toute question :</p>
<div className={styles.infoBox} role="note" aria-label="Coordonnées de contact">
<p><strong>XEFI SA</strong></p>
<p>2507 Avenue de l'Europe 69140 Rillieux-la-Pape</p>
<p>Email : dpo@xefi.fr</p>
</div>
</section>
</main>
<footer className={styles.footer} role="contentinfo">
<p>Data Sentinel v1.0 © XEFI SA 2026</p>
<nav aria-label="Liens légaux">
<a href="/mentions-legales">Mentions légales</a>
</nav>
</footer>
</div>
</div>
);
}
+134
View File
@@ -0,0 +1,134 @@
/* src/pages/CGU/CGU.module.css */
.page {
min-height: 100vh;
background-color: var(--color-white);
color: var(--color-text);
}
.container {
max-width: 760px;
margin: 0 auto;
padding: 24px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 32px;
}
.logo {
font-size: 20px;
font-weight: bold;
color: var(--color-primary);
}
.mainTitle {
font-size: 28px;
font-weight: 700;
color: var(--color-text);
text-align: center;
margin-bottom: 8px;
}
.subtitle {
text-align: center;
color: var(--color-text-secondary);
font-size: 13px;
margin-bottom: 48px;
}
.section {
margin-bottom: 36px;
}
.section h2 {
font-size: 16px;
font-weight: 700;
color: var(--color-text);
margin-bottom: 12px;
padding-left: 14px;
border-left: 4px solid var(--color-primary);
}
.section p {
margin: 8px 0;
line-height: 1.65;
color: var(--color-text-secondary);
}
.list {
list-style: disc;
padding-left: 24px;
margin: 10px 0;
}
.list li {
margin: 6px 0;
line-height: 1.6;
color: var(--color-text-secondary);
}
.infoBox {
background-color: var(--color-gray-light);
border-left: 4px solid var(--color-primary);
border-radius: var(--radius);
padding: 16px 20px;
margin-top: 12px;
}
.infoBox p {
margin: 4px 0;
font-size: 13px;
}
.footer {
margin-top: 64px;
padding: 16px 24px;
background-color: var(--color-black);
color: var(--color-white);
text-align: center;
margin-left: -24px;
margin-right: -24px;
margin-bottom: -24px;
font-size: 13px;
display: flex;
flex-direction: column;
gap: 8px;
}
.footer nav {
display: flex;
justify-content: center;
gap: 16px;
}
.footer nav a {
color: #aaa;
font-size: 12px;
text-decoration: none;
}
.footer nav a:hover {
color: var(--color-white);
text-decoration: underline;
}
/* Responsive */
@media (max-width: 640px) {
.container {
padding: 16px;
}
.mainTitle {
font-size: 22px;
}
.header {
flex-direction: column;
align-items: flex-start;
gap: 12px;
}
}
@@ -108,3 +108,49 @@
padding: 32px 0;
text-align: center;
}
/* Responsive */
@media (max-width: 640px) {
.page {
padding: 12px;
}
.pageHeader {
flex-direction: column;
align-items: flex-start;
gap: 12px;
margin-bottom: 20px;
}
.title {
font-size: 20px;
}
.kpiGrid {
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
.kpiValue {
font-size: 28px;
}
.filtres {
flex-direction: column;
}
.select {
width: 100%;
min-width: unset;
}
.grid {
grid-template-columns: 1fr;
}
}
@media (min-width: 1280px) {
.grid {
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
}
}
@@ -0,0 +1,85 @@
// src/pages/Documentation/Documentation.jsx
// Page documentation technique de Data Sentinel
import { ExternalLink, Book, Code, Database, Shield } from 'lucide-react';
import styles from './Documentation.module.css';
const sections = [
{
icon: Book,
title: 'Guide utilisateur',
items: [
{ label: 'Dashboard — Lecture des KPI et monitorings', desc: 'Comprendre les indicateurs clés : total, sans erreur, en erreur, total erreurs.' },
{ label: 'Vue consolidée — Agrégation par service', desc: 'Analyse croisée des résultats par service métier et catégorie de monitoring.' },
{ label: 'Historique — Export et graphiques', desc: 'Consultation des données passées avec export CSV et visualisation en courbe.' },
{ label: 'Gestion des contrats et fournisseurs', desc: 'Référentiel des contrats de service et fournisseurs associés.' },
],
},
{
icon: Code,
title: 'Architecture technique',
items: [
{ label: 'Frontend — React 18 + Vite', desc: 'SPA React 18 avec CSS Modules, React Router v7, Recharts. Build Vite.' },
{ label: 'Backend — API REST', desc: 'API REST avec authentification JWT. Endpoints documentés via Swagger.' },
{ label: 'Base de données — SQL Server', desc: 'SQL Server avec vues SQL optimisées et jobs CRON pour les agrégations.' },
{ label: 'Infrastructure — NEXERN (XEFI)', desc: 'Hébergement souverain français sur les datacenters NEXERN de XEFI.' },
],
},
{
icon: Database,
title: 'Monitorings disponibles',
items: [
{ label: 'CRM — Données clients et prospects', desc: 'Surveillance de la cohérence et de la complétude des données CRM.' },
{ label: 'Sage — Données comptables et financières', desc: 'Contrôle qualité des flux comptables issus de Sage.' },
{ label: 'Infocentre — Reporting décisionnel', desc: 'Validation des données alimentant les rapports de direction.' },
],
},
{
icon: Shield,
title: 'Sécurité et conformité',
items: [
{ label: 'Authentification JWT', desc: 'Token JWT stocké en sessionStorage, expiration automatique.' },
{ label: 'Contrôle d\'accès RBAC', desc: 'Rôles : Administrateur, Superviseur, Consultant. Accès aux fonctions selon le rôle.' },
{ label: 'Conformité RGPD', desc: 'Conservation 24 mois, DPO joignable sur dpo@xefi.fr, droits exercés à la demande.' },
{ label: 'Accessibilité RGAA / WCAG 2.1 AA', desc: 'Navigation clavier, ARIA, contrastes conformes, responsive 320px1920px.' },
],
},
];
export default function Documentation() {
return (
<div className={styles.page}>
<div className={styles.pageHeader}>
<h1 className={styles.title}>Documentation</h1>
<p className={styles.subtitle}>Référence technique et guide d'utilisation de Data Sentinel</p>
</div>
<div className={styles.grid}>
{sections.map(({ icon: Icon, title, items }) => (
<section key={title} className={styles.card} aria-labelledby={`section-${title.replace(/\s+/g, '-')}`}>
<div className={styles.cardHeader}>
<Icon size={18} className={styles.cardIcon} aria-hidden="true" />
<h2 id={`section-${title.replace(/\s+/g, '-')}`} className={styles.cardTitle}>{title}</h2>
</div>
<ul className={styles.list}>
{items.map(({ label, desc }) => (
<li key={label} className={styles.item}>
<span className={styles.itemLabel}>{label}</span>
<span className={styles.itemDesc}>{desc}</span>
</li>
))}
</ul>
</section>
))}
</div>
<div className={styles.footer}>
<p>Data Sentinel v1.0 — Développé par COYAUD Anthony, Nexa Digital School 2026</p>
<p>
<a href="/cgu" className={styles.link}>CGU</a>
{' · '}
<a href="/mentions-legales" className={styles.link}>Mentions légales</a>
</p>
</div>
</div>
);
}
@@ -0,0 +1,108 @@
/* src/pages/Documentation/Documentation.module.css */
.page {
max-width: 1100px;
}
.pageHeader {
margin-bottom: 32px;
}
.title {
font-size: 22px;
font-weight: 700;
color: var(--color-text);
margin-bottom: 6px;
}
.subtitle {
color: var(--color-text-secondary);
font-size: 13px;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
margin-bottom: 40px;
}
.card {
background-color: var(--color-white);
border: 1px solid var(--color-gray-border);
border-radius: var(--radius);
padding: 20px;
box-shadow: var(--shadow);
}
.cardHeader {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 1px solid var(--color-gray-border);
}
.cardIcon {
color: var(--color-primary);
flex-shrink: 0;
}
.cardTitle {
font-size: 15px;
font-weight: 700;
color: var(--color-text);
}
.list {
display: flex;
flex-direction: column;
gap: 12px;
}
.item {
display: flex;
flex-direction: column;
gap: 2px;
}
.itemLabel {
font-size: 13px;
font-weight: 600;
color: var(--color-text);
}
.itemDesc {
font-size: 12px;
color: var(--color-text-secondary);
line-height: 1.5;
}
.footer {
border-top: 1px solid var(--color-gray-border);
padding-top: 20px;
text-align: center;
font-size: 12px;
color: var(--color-text-secondary);
display: flex;
flex-direction: column;
gap: 6px;
}
.link {
color: var(--color-text-secondary);
text-decoration: none;
}
.link:hover {
color: var(--color-text);
text-decoration: underline;
}
/* Responsive */
@media (max-width: 768px) {
.grid {
grid-template-columns: 1fr;
}
}
@@ -0,0 +1,60 @@
// src/pages/Journal/Journal.jsx
// Page Journal d'audit — historique des actions utilisateurs
import { useState, useEffect } from 'react';
import { getJournal } from '../../services/api';
import DataTable from '../../components/common/DataTable';
import LoadingSpinner from '../../components/common/LoadingSpinner';
import ErrorMessage from '../../components/common/ErrorMessage';
import styles from './Journal.module.css';
export default function Journal() {
const [entries, setEntries] = useState([]);
const [loading, setLoading] = useState(true);
const [erreur, setErreur] = useState('');
useEffect(() => {
async function load() {
setLoading(true);
setErreur('');
try {
const data = await getJournal();
setEntries(Array.isArray(data) ? data : []);
} catch (e) {
setErreur(e.message || 'Erreur lors du chargement du journal.');
} finally {
setLoading(false);
}
}
load();
}, []);
const columns = [
{ key: 'date_action', label: 'Date' },
{ key: 'utilisateur', label: 'Utilisateur' },
{ key: 'action', label: 'Action' },
{ key: 'detail', label: 'Détail' },
{ key: 'ip', label: 'Adresse IP' },
];
return (
<div className={styles.page}>
<h1 className={styles.title}>Journal d'audit</h1>
<p className={styles.description}>
Historique des actions effectuées sur la plateforme par les utilisateurs.
</p>
{loading ? (
<LoadingSpinner message="Chargement du journal..." />
) : erreur ? (
<ErrorMessage message={erreur} />
) : (
<DataTable
columns={columns}
data={entries}
pageSize={50}
emptyMessage="Aucune entrée dans le journal."
/>
)}
</div>
);
}
@@ -0,0 +1,18 @@
/* src/pages/Journal/Journal.module.css */
.page {
max-width: 1200px;
}
.title {
font-size: 22px;
font-weight: 700;
margin-bottom: 8px;
color: var(--color-text);
}
.description {
color: var(--color-text-secondary);
font-size: 13px;
margin-bottom: 24px;
}