feat: add data export functionality to settings page and update admin reports table

- Introduced "Export Data" card in settings for exporting user data as a JSON file.
- Added `exportData` method to `UserService` for handling data export requests.
- Updated admin reports table with a new "Cible" column to display target information.
This commit is contained in:
Mathis HERRIOT
2026-01-29 13:57:07 +01:00
parent 004021ff84
commit aa17c57e26
3 changed files with 74 additions and 2 deletions

View File

@@ -104,6 +104,7 @@ export default function AdminReportsPage() {
<TableHeader>
<TableRow>
<TableHead>Signalé par</TableHead>
<TableHead>Cible</TableHead>
<TableHead>Raison</TableHead>
<TableHead>Description</TableHead>
<TableHead>Statut</TableHead>
@@ -114,13 +115,13 @@ export default function AdminReportsPage() {
<TableBody>
{loading ? (
<TableRow>
<TableCell colSpan={5} className="text-center py-8">
<TableCell colSpan={7} className="text-center py-8">
Chargement...
</TableCell>
</TableRow>
) : reports.length === 0 ? (
<TableRow>
<TableCell colSpan={5} className="text-center py-8">
<TableCell colSpan={7} className="text-center py-8">
Aucun signalement trouvé.
</TableCell>
</TableRow>

View File

@@ -12,6 +12,7 @@ import {
Sun,
Trash2,
User as UserIcon,
Download,
} from "lucide-react";
import { useRouter } from "next/navigation";
import { useTheme } from "next-themes";
@@ -69,6 +70,7 @@ export default function SettingsPage() {
const router = useRouter();
const [isSaving, setIsSaving] = React.useState(false);
const [isDeleting, setIsDeleting] = React.useState(false);
const [isExporting, setIsExporting] = React.useState(false);
const [mounted, setMounted] = React.useState(false);
React.useEffect(() => {
@@ -144,6 +146,29 @@ export default function SettingsPage() {
}
};
const handleExportData = async () => {
setIsExporting(true);
try {
const data = await UserService.exportData();
const blob = new Blob([JSON.stringify(data, null, 2)], {
type: "application/json",
});
const url = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", `memegoat-data-${user?.username}.json`);
document.body.appendChild(link);
link.click();
link.remove();
toast.success("Vos données ont été exportées avec succès.");
} catch (error) {
console.error(error);
toast.error("Erreur lors de l'exportation des données.");
} finally {
setIsExporting(false);
}
};
return (
<div className="max-w-2xl mx-auto py-12 px-4">
<div className="flex items-center gap-3 mb-8">
@@ -294,6 +319,47 @@ export default function SettingsPage() {
</CardContent>
</Card>
<Card className="border-none shadow-sm">
<CardHeader className="pb-4">
<div className="flex items-center gap-2 mb-1">
<Download className="h-5 w-5 text-primary" />
<CardTitle>Portabilité des données</CardTitle>
</div>
<CardDescription>
Conformément au RGPD, vous pouvez exporter l'intégralité de vos données rattachées à votre compte.
</CardDescription>
</CardHeader>
<CardContent>
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 p-4 rounded-lg bg-white dark:bg-zinc-900 border">
<div className="space-y-1">
<p className="font-bold">Exporter mes données</p>
<p className="text-sm text-muted-foreground">
Téléchargez un fichier JSON contenant votre profil, vos mèmes et vos favoris.
</p>
</div>
<Button
variant="outline"
size="sm"
onClick={handleExportData}
disabled={isExporting}
className="font-semibold"
>
{isExporting ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Exportation...
</>
) : (
<>
<Download className="h-4 w-4 mr-2" />
Exporter mes données
</>
)}
</Button>
</div>
</CardContent>
</Card>
<Card className="border-destructive/20 shadow-sm bg-destructive/5">
<CardHeader className="pb-4">
<div className="flex items-center gap-2 mb-1">

View File

@@ -53,4 +53,9 @@ export const UserService = {
});
return data;
},
async exportData(): Promise<any> {
const { data } = await api.get("/users/me/export");
return data;
},
};