admin ui enhacement

This commit is contained in:
dimitar committed 2026-03-18 02:36:12 +01:00
1 parent 02c9681aca
commit 0abb41f573
16 files changed
+988 -435

No files matched your search

+57 -46
View File
@@ -1,49 +1,60 @@
import React from 'react'
import { cn } from '@/lib/utils'
import { Loader2 } from 'lucide-react'
import React from "react";
import { cn } from "@/lib/utils";
import { Loader2 } from "lucide-react";
import { cva, type VariantProps } from "class-variance-authority";
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary' | 'ghost' | 'destructive' | 'outline' | 'default'
size?: 'default' | 'sm' | 'lg' | 'icon'
isLoading?: boolean
children: React.ReactNode
const buttonVariants = cva(
"inline-flex items-center justify-center rounded-lg text-sm font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default:
"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90 hover:shadow",
destructive:
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90 hover:shadow",
outline:
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
);
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
isLoading?: boolean;
}
export function Button({
variant = 'primary',
size = 'default',
isLoading = false,
children,
className = '',
disabled,
...props
}: ButtonProps) {
const baseClasses = 'inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50'
const variantClasses = {
primary: 'bg-blue-600 text-white hover:bg-blue-700 shadow hover:bg-blue-700/90',
default: 'bg-blue-600 text-white hover:bg-blue-700 shadow hover:bg-blue-700/90',
secondary: 'bg-slate-100 text-slate-900 hover:bg-slate-200/80',
ghost: 'hover:bg-slate-100 hover:text-slate-900',
destructive: 'bg-red-500 text-white hover:bg-red-600/90',
outline: 'border border-input bg-transparent shadow-sm hover:bg-slate-100 hover:text-slate-900'
}
const sizeClasses = {
default: 'h-9 px-4 py-2',
sm: 'h-8 rounded-md px-3 text-xs',
lg: 'h-10 rounded-md px-8',
icon: 'h-9 w-9'
}
return (
<button
className={cn(baseClasses, variantClasses[variant], sizeClasses[size], className)}
disabled={disabled || isLoading}
{...props}
>
{isLoading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
{children}
</button>
)
}
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
(
{ className, variant, size, isLoading, children, disabled, ...props },
ref,
) => {
return (
<button
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
disabled={disabled || isLoading}
{...props}
>
{isLoading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
{children}
</button>
);
},
);
Button.displayName = "Button";