New Layout

This commit is contained in:
Marco Santos
2025-07-13 21:43:37 +01:00
parent f51e5dea31
commit 11e532ac9a
183 changed files with 1621 additions and 8377 deletions

View File

@@ -0,0 +1,51 @@
// components/ui/Button.tsx
import type { ReactNode } from "react";
import { Loader2 } from "lucide-react";
import { twMerge } from "tailwind-merge";
type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
icon?: ReactNode;
variant?: "primary" | "secondary" | "ghost" | "danger";
loading?: boolean;
};
export function Button({
icon,
variant = "primary",
children,
className = "",
type = "button",
loading = false,
disabled,
...rest
}: ButtonProps) {
const base =
"inline-flex items-center justify-center gap-2 rounded-2xl px-5 py-2.5 font-medium text-sm transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed shadow-sm hover:shadow-md";
const variants = {
primary: "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500",
secondary:
"bg-zinc-100 text-zinc-900 hover:bg-zinc-200 dark:bg-zinc-700 dark:text-white dark:hover:bg-zinc-600 focus:ring-zinc-400",
ghost:
"bg-transparent text-zinc-700 hover:bg-zinc-100 dark:text-zinc-200 dark:hover:bg-zinc-800 focus:ring-zinc-300",
danger: "bg-red-600 text-white hover:bg-red-700 focus:ring-red-500",
};
return (
<button
type={type}
className={twMerge(base, variants[variant], className)}
disabled={disabled || loading}
{...rest}
>
{loading ? (
<Loader2 className="animate-spin w-4 h-4" />
) : (
<>
{icon && <span className="w-4 h-4">{icon}</span>}
{children}
</>
)}
</button>
);
}