ppt-tool/frontend/app/(presentation-generator)/custom-template/components/SaveLayoutButton.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

39 lines
No EOL
981 B
TypeScript

import React from "react";
import { Button } from "@/components/ui/button";
import { FileText, Loader2 } from "lucide-react";
interface SaveLayoutButtonProps {
onSave: () => void;
isSaving: boolean;
isProcessing: boolean;
}
export const SaveLayoutButton: React.FC<SaveLayoutButtonProps> = ({
onSave,
isSaving,
isProcessing,
}) => {
return (
<div className="fixed bottom-6 left-1/2 -translate-x-1/2 z-50">
<Button
onClick={onSave}
disabled={isSaving || isProcessing}
className="bg-green-600 hover:bg-green-700 text-white shadow-lg hover:shadow-xl transition-all duration-200 px-10 py-3 text-lg"
size="lg"
>
{isSaving ? (
<>
<Loader2 className="w-5 h-5 mr-2 animate-spin" />
Saving Template...
</>
) : (
<>
<FileText className="w-5 h-5 mr-2" />
Save as Template
</>
)}
</Button>
</div>
);
};