- AppReport entity + migration (type, message, fingerprint SHA-256, created_at) - POST /api/report avec rate-limit 5/heure par fingerprint IP - ReportModal : formulaire type radio (bug/idée) + textarea 1 000 chars max - ChangelogModal : fonctionnalités en prod, roadmap, 5 limitations honnêtes - Deux boutons flottants bas-gauche (? info + ✉ signalement) - Légende remontée pour éviter le chevauchement Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
67 lines
2.0 KiB
JavaScript
67 lines
2.0 KiB
JavaScript
import { useState } from 'react';
|
|
import SargassesMap from './components/Map/SargassesMap';
|
|
import SpotPanel from './components/SpotPanel/SpotPanel';
|
|
import Topbar from './components/Topbar/Topbar';
|
|
import Legend from './components/Legend/Legend';
|
|
import ReportModal from './components/ReportModal/ReportModal';
|
|
import ChangelogModal from './components/ChangelogModal/ChangelogModal';
|
|
import './App.css';
|
|
|
|
export default function App() {
|
|
const [selectedSpot, setSelectedSpot] = useState(null);
|
|
const [activeStep, setActiveStep] = useState('now');
|
|
const [flyToTarget, setFlyToTarget] = useState(null);
|
|
const [showReport, setShowReport] = useState(false);
|
|
const [showChangelog, setShowChangelog] = useState(false);
|
|
|
|
return (
|
|
<div className="app">
|
|
<Topbar
|
|
activeStep={activeStep}
|
|
onStepChange={setActiveStep}
|
|
onIslandSelect={setFlyToTarget}
|
|
/>
|
|
|
|
<div className="app__wave-overlay" aria-hidden="true" />
|
|
|
|
<SargassesMap
|
|
onSpotSelect={setSelectedSpot}
|
|
selectedSpotId={selectedSpot?.id}
|
|
activeStep={activeStep}
|
|
flyToTarget={flyToTarget}
|
|
/>
|
|
|
|
<Legend />
|
|
|
|
{/* Boutons flottants bas-gauche */}
|
|
<div className="app__actions">
|
|
<button
|
|
className="app__action-btn app__action-btn--info"
|
|
onClick={() => setShowChangelog(true)}
|
|
title="À propos / changelog"
|
|
aria-label="À propos"
|
|
>
|
|
?
|
|
</button>
|
|
<button
|
|
className="app__action-btn app__action-btn--report"
|
|
onClick={() => setShowReport(true)}
|
|
title="Signaler un bug ou soumettre une idée"
|
|
aria-label="Signalement"
|
|
>
|
|
✉
|
|
</button>
|
|
</div>
|
|
|
|
<SpotPanel
|
|
spot={selectedSpot}
|
|
activeStep={activeStep}
|
|
onClose={() => setSelectedSpot(null)}
|
|
/>
|
|
|
|
{showReport && <ReportModal onClose={() => setShowReport(false)} />}
|
|
{showChangelog && <ChangelogModal onClose={() => setShowChangelog(false)} />}
|
|
</div>
|
|
);
|
|
}
|