feat(newwhats): frontend do plugin (Inbox/Sessions/Secretária) em tela cheia
- /wa-inbox, /wa-sessions e /wa-secretaria rodam sem a sidebar do scoreodonto (isStandaloneView); cada tela tem seu "Voltar" (Secretária ganhou botão na ThinNav). - SessionsView: banner "Você já possui acesso ao WhatsApp" quando há sessão ativa. - avatares: usa a URL do CDN (contactAvatarUrl/instance.avatar) direto; Avatar exibe sem depender de version; self-heal no onError re-busca a foto atual. - deps: framer-motion, immer. Dev override com HMR (docker-compose.dev.yml). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
// Button do motor NewWhats (de @/components/ui) — portado para o satélite.
|
||||
import React from 'react';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
|
||||
type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'premium';
|
||||
type ButtonSize = 'sm' | 'md' | 'lg';
|
||||
|
||||
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
variant?: ButtonVariant;
|
||||
size?: ButtonSize;
|
||||
loading?: boolean;
|
||||
icon?: React.ReactNode;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const variantClasses: Record<ButtonVariant, string> = {
|
||||
primary: 'bg-brand-500 text-white font-bold shadow-lg shadow-brand-500/20 hover:bg-brand-600 active:scale-[0.98]',
|
||||
secondary: 'bg-white/5 border border-white/10 text-white font-semibold hover:bg-white/10 backdrop-blur-sm',
|
||||
ghost: 'text-slate-400 hover:text-white hover:bg-white/5',
|
||||
danger: 'bg-red-500/10 text-red-400 border border-red-500/20 hover:bg-red-500/20',
|
||||
premium: 'bg-gradient-to-r from-brand-500 to-blue-500 text-white font-bold shadow-glow-brand hover:shadow-lg active:scale-[0.98] relative overflow-hidden',
|
||||
};
|
||||
|
||||
const sizeClasses: Record<ButtonSize, string> = {
|
||||
sm: 'px-3 py-1.5 text-xs rounded-lg gap-1.5',
|
||||
md: 'px-4 py-2.5 text-sm rounded-xl gap-2',
|
||||
lg: 'px-6 py-3.5 text-sm rounded-xl gap-2',
|
||||
};
|
||||
|
||||
export function Button({
|
||||
variant = 'primary',
|
||||
size = 'md',
|
||||
loading,
|
||||
icon,
|
||||
children,
|
||||
className = '',
|
||||
disabled,
|
||||
...props
|
||||
}: ButtonProps) {
|
||||
return (
|
||||
<button
|
||||
disabled={disabled || loading}
|
||||
className={`
|
||||
inline-flex items-center justify-center transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed
|
||||
${variantClasses[variant]} ${sizeClasses[size]} ${className}
|
||||
`}
|
||||
{...props}
|
||||
>
|
||||
{loading ? <Loader2 className="w-4 h-4 animate-spin" /> : icon ? icon : null}
|
||||
{children}
|
||||
{variant === 'premium' && (
|
||||
<div className="absolute inset-0 -translate-x-full animate-shimmer bg-gradient-to-r from-transparent via-white/10 to-transparent pointer-events-none" />
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export default Button;
|
||||
Reference in New Issue
Block a user