Security Improvements (P0.0-P0.4): - P0.0: Migrate to Gemini-only AI stack (simplified, single billing) - P0.1: Fix CORS to restrict allowed origins from env (was *) - P0.2: Remove hardcoded dev password, require env var - P0.3: Add rate limiting (slowapi) - 3-10 req/min on sensitive endpoints - P0.4: Add request size limits (100MB default via middleware) New Features: - Unified LLM service with Google Gemini priority - OXML geometry extractor for layout parsing - TSX validator for generated React components - Client ID support in presentation requests with access control - Configurable LLM/image timeouts via env vars Modern Design System (P0.9 - partial): - Enhanced CSS design tokens (primary, semantic colors, shadows) - Typography scale (h1-h4, body variants, caption) - Modern animations (fadeIn, slideIn, scaleIn) - Updated Button component with better variants and hover effects - Created unified Card and StatusBadge components - Applied design system to Dashboard and Settings pages Backend Improvements: - Master deck parser simplification - Slide-to-HTML endpoint cleanup (325 lines removed) - Better error handling in prompts endpoint Frontend Improvements: - Settings UI simplified to show only Google/Gemini - Dashboard uses CSS variables instead of hardcoded colors - Improved button transitions and hover states Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
69 lines
1.7 KiB
TypeScript
69 lines
1.7 KiB
TypeScript
import { cn } from "@/lib/utils";
|
|
|
|
interface CardProps {
|
|
children: React.ReactNode;
|
|
hover?: boolean;
|
|
className?: string;
|
|
onClick?: () => void;
|
|
}
|
|
|
|
export function Card({ children, hover = false, className = "", onClick }: CardProps) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"bg-white rounded-xl border border-border p-6",
|
|
"transition-all duration-200",
|
|
hover && "hover:shadow-lg hover:border-[hsl(var(--primary))]/20 cursor-pointer hover:-translate-y-1",
|
|
className
|
|
)}
|
|
onClick={onClick}
|
|
>
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface CardHeaderProps {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
export function CardHeader({ children, className = "" }: CardHeaderProps) {
|
|
return <div className={cn("mb-4", className)}>{children}</div>;
|
|
}
|
|
|
|
interface CardTitleProps {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
export function CardTitle({ children, className = "" }: CardTitleProps) {
|
|
return <h3 className={cn("text-xl font-semibold", className)}>{children}</h3>;
|
|
}
|
|
|
|
interface CardDescriptionProps {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
export function CardDescription({ children, className = "" }: CardDescriptionProps) {
|
|
return <p className={cn("text-sm text-muted-foreground", className)}>{children}</p>;
|
|
}
|
|
|
|
interface CardContentProps {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
export function CardContent({ children, className = "" }: CardContentProps) {
|
|
return <div className={cn(className)}>{children}</div>;
|
|
}
|
|
|
|
interface CardFooterProps {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
export function CardFooter({ children, className = "" }: CardFooterProps) {
|
|
return <div className={cn("mt-4 pt-4 border-t border-border", className)}>{children}</div>;
|
|
}
|