ppt-tool/frontend/app/admin/components/DataExportButton.tsx
Vadym Samoilenko cf21ba4516 Phase 1-2: Foundation + Admin Panel & Client Management
Phase 1 (Foundation):
- Project restructure (presenton-main → backend/ + frontend/)
- Database schema (8 new models, Alembic config, seed script)
- Auth (Azure AD SSO + dev bypass, JWT sessions, AuthMiddleware)
- RBAC (access_service, rbac_middleware, admin routers)
- Audit logging (fire-and-forget, AuditMiddleware, admin router)
- i18n (react-i18next with 5 namespace files)

Phase 2 (Admin Panel & Client Management):
- Admin panel shell (sidebar layout, role guard, 12 pages)
- Redux admin slice with 18 async thunks
- User management (role changes, deactivation)
- Client management (CRUD, brand config, team management)
- Brand config editor (colors, fonts, logos, voice rules)
- Master deck upload & parser (PPTX → HTML → React pipeline)
- Audit log viewer with filters and CSV/JSON export

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 15:37:17 +00:00

58 lines
1.5 KiB
TypeScript

'use client';
import { useState } from 'react';
import { Button } from '@/components/ui/button';
import { Download } from 'lucide-react';
interface DataExportButtonProps {
endpoint: string;
params?: Record<string, string>;
}
export default function DataExportButton({ endpoint, params }: DataExportButtonProps) {
const [loading, setLoading] = useState(false);
const handleExport = async (format: 'csv' | 'json') => {
setLoading(true);
try {
const query = new URLSearchParams({ format, ...params });
const res = await fetch(`${endpoint}?${query.toString()}`);
if (!res.ok) throw new Error('Export failed');
const blob = await res.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `export.${format}`;
a.click();
URL.revokeObjectURL(url);
} catch {
// Error handled silently — toast can be added later
} finally {
setLoading(false);
}
};
return (
<div className="flex gap-2">
<Button
variant="outline"
size="sm"
onClick={() => handleExport('csv')}
disabled={loading}
>
<Download className="w-4 h-4 mr-1" />
CSV
</Button>
<Button
variant="outline"
size="sm"
onClick={() => handleExport('json')}
disabled={loading}
>
<Download className="w-4 h-4 mr-1" />
JSON
</Button>
</div>
);
}