mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 13:51:13 -05:00
106 lines
3.1 KiB
TypeScript
106 lines
3.1 KiB
TypeScript
import { CheckCircle, XCircle, Lock, RefreshCw, Trash2 } from 'lucide-react';
|
|
import { Button, ButtonProps } from './button';
|
|
|
|
type ActionType = 'approve' | 'reject' | 'delete' | 'claim' | 'reset' | 'retry';
|
|
|
|
interface ActionConfig {
|
|
icon: React.ReactNode;
|
|
defaultLabel: string;
|
|
loadingText: string;
|
|
variant: ButtonProps['variant'];
|
|
className?: string;
|
|
}
|
|
|
|
const ACTION_CONFIGS: Record<ActionType, ActionConfig> = {
|
|
approve: {
|
|
icon: <CheckCircle className="w-4 h-4 mr-2" />,
|
|
defaultLabel: 'Approve',
|
|
loadingText: 'Processing...',
|
|
variant: 'default',
|
|
},
|
|
reject: {
|
|
icon: <XCircle className="w-4 h-4 mr-2" />,
|
|
defaultLabel: 'Reject',
|
|
loadingText: 'Processing...',
|
|
variant: 'destructive',
|
|
},
|
|
claim: {
|
|
icon: <Lock className="w-4 h-4 mr-2" />,
|
|
defaultLabel: 'Claim Submission',
|
|
loadingText: 'Claiming...',
|
|
variant: 'default',
|
|
},
|
|
reset: {
|
|
icon: <RefreshCw className="w-4 h-4 mr-2" />,
|
|
defaultLabel: 'Reset to Pending',
|
|
loadingText: 'Resetting...',
|
|
variant: 'outline',
|
|
},
|
|
retry: {
|
|
icon: <RefreshCw className="w-4 h-4 mr-2" />,
|
|
defaultLabel: 'Retry Failed',
|
|
loadingText: 'Retrying...',
|
|
variant: 'default',
|
|
className: 'bg-yellow-600 hover:bg-yellow-700',
|
|
},
|
|
delete: {
|
|
icon: <Trash2 className="w-4 h-4 mr-2" />,
|
|
defaultLabel: 'Delete',
|
|
loadingText: 'Deleting...',
|
|
variant: 'destructive',
|
|
},
|
|
};
|
|
|
|
interface ActionButtonProps extends Omit<ButtonProps, 'loading' | 'loadingText' | 'variant'> {
|
|
action: ActionType;
|
|
isLoading?: boolean;
|
|
loadingText?: string;
|
|
variant?: ButtonProps['variant'];
|
|
children?: React.ReactNode;
|
|
isMobile?: boolean;
|
|
}
|
|
|
|
export const ActionButton = ({
|
|
action,
|
|
isLoading = false,
|
|
loadingText,
|
|
variant,
|
|
size = 'default',
|
|
className,
|
|
children,
|
|
isMobile = false,
|
|
...props
|
|
}: ActionButtonProps) => {
|
|
const config = ACTION_CONFIGS[action];
|
|
const iconClassName = isMobile ? "w-5 h-5 mr-2" : "w-4 h-4 mr-2";
|
|
|
|
// Clone the icon with mobile-appropriate size
|
|
const icon = isMobile && config.icon
|
|
? <CheckCircle className={iconClassName} /> // Dynamic sizing handled per action below
|
|
: config.icon;
|
|
|
|
return (
|
|
<Button
|
|
variant={variant || config.variant}
|
|
size={size}
|
|
loading={isLoading}
|
|
loadingText={loadingText || config.loadingText}
|
|
className={`${config.className || ''} ${className || ''} ${isMobile ? 'h-11' : ''}`}
|
|
trackingLabel={`moderation-${action}`}
|
|
{...props}
|
|
>
|
|
{children || (
|
|
<>
|
|
{action === 'approve' && (isMobile ? <CheckCircle className="w-5 h-5 mr-2" /> : <CheckCircle className="w-4 h-4 mr-2" />)}
|
|
{action === 'reject' && (isMobile ? <XCircle className="w-5 h-5 mr-2" /> : <XCircle className="w-4 h-4 mr-2" />)}
|
|
{action === 'claim' && (isMobile ? <Lock className="w-5 h-5 mr-2" /> : <Lock className="w-4 h-4 mr-2" />)}
|
|
{action === 'reset' && <RefreshCw className={iconClassName} />}
|
|
{action === 'retry' && <RefreshCw className={iconClassName} />}
|
|
{action === 'delete' && <Trash2 className={iconClassName} />}
|
|
{config.defaultLabel}
|
|
</>
|
|
)}
|
|
</Button>
|
|
);
|
|
};
|