Skip to content

Commit cdb576c

Browse files
committed
maquette Export des données d'autosurveillance brute
1 parent b3fc802 commit cdb576c

File tree

4 files changed

+114
-0
lines changed

4 files changed

+114
-0
lines changed

apps/front/src/App.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { SuiviMesuresPage } from './pages/SuiviMesures';
1111
import { SuiviDecisionsPage } from './pages/SuiviDecisions';
1212
import { SuiviDepotsPage } from './pages/SuiviDepots';
1313
import { SuiviConformitePage } from './pages/SuiviConformite';
14+
import { ExportDonneesPage } from './pages/ExportDonnees';
1415
import CallbackPage from './pages/CallbackPage';
1516
import MockAuthorizationPage from './pages/MockAuthorizationPage';
1617
import { AppHeader } from './components/Header';
@@ -142,6 +143,14 @@ function App() {
142143
</ProtectedRoute>
143144
}
144145
/>
146+
<Route
147+
path={AppRoutes.EXPORT_DONNEES}
148+
element={
149+
<ProtectedRoute>
150+
<ExportDonneesPage />
151+
</ProtectedRoute>
152+
}
153+
/>
145154
</Routes>
146155
</main>
147156
</div>

apps/front/src/components/Header.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ export function AppHeader() {
9494
linkProps: { href: AppRoutes.SUIVI_CONFORMITE },
9595
isActive: isNavItemActive(AppRoutes.SUIVI_CONFORMITE),
9696
},
97+
{
98+
text: 'Export des données',
99+
linkProps: { href: AppRoutes.EXPORT_DONNEES },
100+
isActive: isNavItemActive(AppRoutes.EXPORT_DONNEES),
101+
},
97102
{
98103
text: 'Historique des décisions',
99104
linkProps: { href: AppRoutes.SUIVI_DECISIONS },
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { useState, useMemo } from 'react';
2+
import { fr } from '@codegouvfr/react-dsfr';
3+
import { Button } from '@codegouvfr/react-dsfr/Button';
4+
import { Input } from '@codegouvfr/react-dsfr/Input';
5+
import { Select } from '@codegouvfr/react-dsfr/Select';
6+
import { Alert } from '@codegouvfr/react-dsfr/Alert';
7+
import { MOCK_MESURES } from '../data/mockMesures';
8+
9+
export const ExportDonneesPage = () => {
10+
const [ouvrage, setOuvrage] = useState('');
11+
const [dateDebut, setDateDebut] = useState('');
12+
const [dateFin, setDateFin] = useState('');
13+
const [type, setType] = useState('Complet');
14+
15+
const ouvrages = useMemo(() => Array.from(new Set(MOCK_MESURES.map((m) => m.ouvrage))), []);
16+
17+
const handleExport = () => {
18+
const filtered = MOCK_MESURES.filter((m) => {
19+
return (
20+
(ouvrage === '' || m.ouvrage === ouvrage) &&
21+
(dateDebut === '' || m.date >= dateDebut) &&
22+
(dateFin === '' || m.date <= dateFin) &&
23+
(type === 'Complet' || m.qualification === type)
24+
);
25+
});
26+
27+
const headers = ['Date', 'Ouvrage', 'Point de mesure', 'Paramètre', 'Valeur', 'Qualification'];
28+
const rows = filtered.map((m) => [
29+
m.date,
30+
m.ouvrage,
31+
m.pointMesure,
32+
m.parametre,
33+
`${m.valeur} ${m.unite}`,
34+
m.qualification,
35+
]);
36+
37+
const csvContent = [headers, ...rows].map((row) => row.join(',')).join('\n');
38+
const blob = new Blob([csvContent], { type: 'text/csv' });
39+
const url = window.URL.createObjectURL(blob);
40+
41+
const a = document.createElement('a');
42+
a.href = url;
43+
a.download = `export_autosurveillance_${new Date().toISOString().slice(0, 10)}.csv`;
44+
a.click();
45+
};
46+
47+
return (
48+
<div className={fr.cx('fr-container', 'fr-py-4w')}>
49+
<h1 className={fr.cx('fr-h1')}>Export des données</h1>
50+
<p className={fr.cx('fr-text--lead')}>Extrayez vos données d'autosurveillance pour vos analyses externes.</p>
51+
52+
<Alert small description="Données basées sur le référentiel J-7." severity="info" className={fr.cx('fr-mb-4w')} />
53+
54+
<div className={fr.cx('fr-grid-row', 'fr-grid-row--gutters', 'fr-mb-4w')}>
55+
<div className={fr.cx('fr-col-12', 'fr-col-md-3')}>
56+
<Select label="Ouvrage" nativeSelectProps={{ onChange: (e) => setOuvrage(e.target.value), value: ouvrage }}>
57+
<option value="">Tous les ouvrages</option>
58+
{ouvrages.map((o) => (
59+
<option key={o} value={o}>
60+
{o}
61+
</option>
62+
))}
63+
</Select>
64+
</div>
65+
<div className={fr.cx('fr-col-12', 'fr-col-md-3')}>
66+
<Input
67+
label="Date de début"
68+
nativeInputProps={{
69+
type: 'date',
70+
onChange: (e) => setDateDebut(e.target.value),
71+
value: dateDebut,
72+
}}
73+
/>
74+
</div>
75+
<div className={fr.cx('fr-col-12', 'fr-col-md-3')}>
76+
<Input
77+
label="Date de fin"
78+
nativeInputProps={{
79+
type: 'date',
80+
onChange: (e) => setDateFin(e.target.value),
81+
value: dateFin,
82+
}}
83+
/>
84+
</div>
85+
<div className={fr.cx('fr-col-12', 'fr-col-md-3')}>
86+
<Select label="Type de données" nativeSelectProps={{ onChange: (e) => setType(e.target.value), value: type }}>
87+
<option value="Complet">Complet</option>
88+
<option value="Brut">Brut</option>
89+
<option value="Qualifié">Qualifié</option>
90+
</Select>
91+
</div>
92+
</div>
93+
94+
<Button onClick={handleExport} iconId="fr-icon-download-line">
95+
Télécharger l'export (CSV)
96+
</Button>
97+
</div>
98+
);
99+
};

apps/front/src/routes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const AppRoutes = {
1313
SUIVI_DECISIONS: '/suivi/decisions',
1414
SUIVI_DEPOTS: '/suivi/depots',
1515
SUIVI_CONFORMITE: '/suivi/conformite',
16+
EXPORT_DONNEES: '/export/donnees',
1617
} as const;
1718

1819
export const getControleRoute = (depotId: string) => `/controle/${depotId}`;

0 commit comments

Comments
 (0)