Extract reusable UI components to reduce DRY violations
- Created StatusBadge component: Standardizes status badge display - Supports tradeStatus prop for trade-specific styling - Supports variant prop for simple badges (success/error/ready) - Eliminates repetitive badge style combinations - Created EmptyState component: Standardizes empty state display - Handles loading and empty states consistently - Supports message, hint, and action props - Used across trades, invites, admin pages - Created ConfirmationButton component: Standardizes confirmation flows - Two-step confirmation pattern (action -> confirm/cancel) - Supports different variants (danger/success/primary) - Handles loading states automatically - Used for cancel, complete, no-show actions - Migrated pages to use new components: - trades/page.tsx: StatusBadge, EmptyState, ConfirmationButton - trades/[id]/page.tsx: StatusBadge - invites/page.tsx: StatusBadge, EmptyState - admin/trades/page.tsx: StatusBadge, EmptyState, ConfirmationButton - admin/invites/page.tsx: StatusBadge Benefits: - Eliminated ~50+ lines of repetitive badge styling code - Consistent UI patterns across all pages - Easier to maintain and update styling - Better type safety All tests passing (32 frontend, 33 e2e)
This commit is contained in:
parent
b86b506d72
commit
1a47b3643f
9 changed files with 309 additions and 425 deletions
52
frontend/app/components/StatusBadge.tsx
Normal file
52
frontend/app/components/StatusBadge.tsx
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import { badgeStyles } from "../styles/shared";
|
||||
import { getTradeStatusDisplay } from "../utils/exchange";
|
||||
|
||||
type StatusBadgeVariant = "success" | "error" | "ready";
|
||||
|
||||
interface StatusBadgeProps {
|
||||
/** Status text to display */
|
||||
children: React.ReactNode;
|
||||
/** Optional variant for simple status badges */
|
||||
variant?: StatusBadgeVariant;
|
||||
/** Trade status (uses getTradeStatusDisplay for styling) */
|
||||
tradeStatus?: string;
|
||||
/** Custom style override */
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standardized status badge component.
|
||||
* Can be used with a variant prop for simple badges, or tradeStatus prop for trade-specific styling.
|
||||
*/
|
||||
export function StatusBadge({ children, variant, tradeStatus, style }: StatusBadgeProps) {
|
||||
let badgeStyle: React.CSSProperties = { ...badgeStyles.badge };
|
||||
|
||||
if (tradeStatus) {
|
||||
// Use trade status display utility for trade-specific badges
|
||||
const statusDisplay = getTradeStatusDisplay(tradeStatus);
|
||||
badgeStyle = {
|
||||
...badgeStyle,
|
||||
background: statusDisplay.bgColor,
|
||||
color: statusDisplay.textColor,
|
||||
};
|
||||
} else if (variant) {
|
||||
// Use variant styles for simple badges
|
||||
switch (variant) {
|
||||
case "success":
|
||||
badgeStyle = { ...badgeStyle, ...badgeStyles.badgeSuccess };
|
||||
break;
|
||||
case "error":
|
||||
badgeStyle = { ...badgeStyle, ...badgeStyles.badgeError };
|
||||
break;
|
||||
case "ready":
|
||||
badgeStyle = { ...badgeStyle, ...badgeStyles.badgeReady };
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<span style={{ ...badgeStyle, ...style }}>
|
||||
{tradeStatus ? getTradeStatusDisplay(tradeStatus).text : children}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue