Add statuscard changes
This commit is contained in:
@@ -79,10 +79,10 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>(({
|
||||
|
||||
const sizeClasses = {
|
||||
xs: 'px-2 py-1 text-xs gap-1 min-h-6',
|
||||
sm: 'px-3 py-1.5 text-sm gap-1.5 min-h-8',
|
||||
md: 'px-4 py-2 text-sm gap-2 min-h-10',
|
||||
lg: 'px-6 py-2.5 text-base gap-2 min-h-12',
|
||||
xl: 'px-8 py-3 text-lg gap-3 min-h-14'
|
||||
sm: 'px-3 py-1.5 text-sm gap-1.5 min-h-8 sm:min-h-10', // Better touch target on mobile
|
||||
md: 'px-4 py-2 text-sm gap-2 min-h-10 sm:min-h-12',
|
||||
lg: 'px-6 py-2.5 text-base gap-2 min-h-12 sm:min-h-14',
|
||||
xl: 'px-8 py-3 text-lg gap-3 min-h-14 sm:min-h-16'
|
||||
};
|
||||
|
||||
const loadingSpinner = (
|
||||
|
||||
@@ -34,9 +34,12 @@ export interface StatusCardProps {
|
||||
icon?: LucideIcon;
|
||||
variant?: 'primary' | 'outline';
|
||||
onClick: () => void;
|
||||
priority?: 'primary' | 'secondary' | 'tertiary';
|
||||
destructive?: boolean;
|
||||
}>;
|
||||
onClick?: () => void;
|
||||
className?: string;
|
||||
compact?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,7 +77,7 @@ export const getStatusColor = (status: string): StatusIndicatorConfig['color'] =
|
||||
* StatusCard - Reusable card component with consistent status styling
|
||||
*/
|
||||
export const StatusCard: React.FC<StatusCardProps> = ({
|
||||
id,
|
||||
id: _id,
|
||||
statusIndicator,
|
||||
title,
|
||||
subtitle,
|
||||
@@ -86,10 +89,23 @@ export const StatusCard: React.FC<StatusCardProps> = ({
|
||||
actions = [],
|
||||
onClick,
|
||||
className = '',
|
||||
compact: _compact = false,
|
||||
}) => {
|
||||
const StatusIcon = statusIndicator.icon;
|
||||
const hasInteraction = onClick || actions.length > 0;
|
||||
|
||||
// Sort actions by priority
|
||||
const sortedActions = [...actions].sort((a, b) => {
|
||||
const priorityOrder = { primary: 0, secondary: 1, tertiary: 2 };
|
||||
const aPriority = priorityOrder[a.priority || 'secondary'];
|
||||
const bPriority = priorityOrder[b.priority || 'secondary'];
|
||||
return aPriority - bPriority;
|
||||
});
|
||||
|
||||
// Split actions into primary and secondary groups
|
||||
const primaryActions = sortedActions.filter(action => action.priority === 'primary');
|
||||
const secondaryActions = sortedActions.filter(action => action.priority !== 'primary');
|
||||
|
||||
return (
|
||||
<Card
|
||||
className={`
|
||||
@@ -201,21 +217,65 @@ export const StatusCard: React.FC<StatusCardProps> = ({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Actions */}
|
||||
{/* Enhanced Mobile-Responsive Actions */}
|
||||
{actions.length > 0 && (
|
||||
<div className="flex gap-2 pt-3 border-t border-[var(--border-primary)]">
|
||||
{actions.map((action, index) => (
|
||||
<Button
|
||||
key={index}
|
||||
variant={action.variant || 'outline'}
|
||||
size="sm"
|
||||
className="flex-1"
|
||||
onClick={action.onClick}
|
||||
>
|
||||
{action.icon && <action.icon className="w-4 h-4 mr-2" />}
|
||||
{action.label}
|
||||
</Button>
|
||||
))}
|
||||
<div className="pt-3 border-t border-[var(--border-primary)]">
|
||||
{/* Primary Actions - Full width on mobile, inline on desktop */}
|
||||
{primaryActions.length > 0 && (
|
||||
<div className={`
|
||||
flex gap-2 mb-2
|
||||
${primaryActions.length > 1 ? 'flex-col sm:flex-row' : ''}
|
||||
`}>
|
||||
{primaryActions.map((action, index) => (
|
||||
<Button
|
||||
key={`primary-${index}`}
|
||||
variant={action.destructive ? 'outline' : (action.variant || 'primary')}
|
||||
size="sm"
|
||||
className={`
|
||||
${primaryActions.length === 1 ? 'w-full sm:w-auto sm:min-w-[120px]' : 'flex-1'}
|
||||
${action.destructive ? 'text-red-600 border-red-300 hover:bg-red-50 hover:border-red-400' : ''}
|
||||
font-medium transition-all duration-200
|
||||
`}
|
||||
onClick={action.onClick}
|
||||
>
|
||||
{action.icon && <action.icon className="w-4 h-4 mr-2 flex-shrink-0" />}
|
||||
<span className="truncate">{action.label}</span>
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Secondary Actions - Compact horizontal layout */}
|
||||
{secondaryActions.length > 0 && (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{secondaryActions.map((action, index) => (
|
||||
<Button
|
||||
key={`secondary-${index}`}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className={`
|
||||
flex-shrink-0 min-w-0
|
||||
${action.destructive ? 'text-red-600 border-red-300 hover:bg-red-50 hover:border-red-400' : ''}
|
||||
${secondaryActions.length > 3 ? 'text-xs px-2' : 'text-sm px-3'}
|
||||
transition-all duration-200
|
||||
`}
|
||||
onClick={action.onClick}
|
||||
>
|
||||
{action.icon && <action.icon className={`
|
||||
${secondaryActions.length > 3 ? 'w-3 h-3' : 'w-4 h-4'}
|
||||
${action.label ? 'mr-1 sm:mr-2' : ''}
|
||||
flex-shrink-0
|
||||
`} />}
|
||||
<span className={`
|
||||
${secondaryActions.length > 3 ? 'hidden sm:inline' : ''}
|
||||
truncate
|
||||
`}>
|
||||
{action.label}
|
||||
</span>
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user