mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-03 21:03:08 +00:00
refactor: simplify EmptyStateCard and update empty state configurations
- Removed unused properties and state management from the EmptyStateCard component for cleaner code. - Updated the EMPTY_STATE_CONFIGS to remove exampleCard entries, streamlining the empty state configuration. - Enhanced the primary action handling in the EmptyStateCard for improved functionality.
This commit is contained in:
@@ -1,20 +1,10 @@
|
|||||||
import { memo, useState } from 'react';
|
import { memo } from 'react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Kbd } from '@/components/ui/kbd';
|
import { Kbd } from '@/components/ui/kbd';
|
||||||
import { formatShortcut } from '@/store/app-store';
|
import { formatShortcut } from '@/store/app-store';
|
||||||
import { getEmptyStateConfig, type EmptyStateConfig } from '../constants';
|
import { getEmptyStateConfig, type EmptyStateConfig } from '../constants';
|
||||||
import {
|
import { Lightbulb, Play, Clock, CheckCircle2, Sparkles, Wand2 } from 'lucide-react';
|
||||||
Lightbulb,
|
|
||||||
Play,
|
|
||||||
Clock,
|
|
||||||
CheckCircle2,
|
|
||||||
Sparkles,
|
|
||||||
Wand2,
|
|
||||||
X,
|
|
||||||
Eye,
|
|
||||||
EyeOff,
|
|
||||||
} from 'lucide-react';
|
|
||||||
|
|
||||||
const ICON_MAP = {
|
const ICON_MAP = {
|
||||||
lightbulb: Lightbulb,
|
lightbulb: Lightbulb,
|
||||||
@@ -51,43 +41,14 @@ export const EmptyStateCard = memo(function EmptyStateCard({
|
|||||||
onAiSuggest,
|
onAiSuggest,
|
||||||
customConfig,
|
customConfig,
|
||||||
}: EmptyStateCardProps) {
|
}: EmptyStateCardProps) {
|
||||||
const [isDismissed, setIsDismissed] = useState(false);
|
|
||||||
const [isMinimized, setIsMinimized] = useState(false);
|
|
||||||
|
|
||||||
// Get base config and merge with custom overrides
|
// Get base config and merge with custom overrides
|
||||||
const baseConfig = getEmptyStateConfig(columnId);
|
const baseConfig = getEmptyStateConfig(columnId);
|
||||||
const config: EmptyStateConfig = { ...baseConfig, ...customConfig };
|
const config: EmptyStateConfig = { ...baseConfig, ...customConfig };
|
||||||
|
|
||||||
// Handle dismissal
|
|
||||||
if (isDismissed) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const IconComponent = ICON_MAP[config.icon];
|
const IconComponent = ICON_MAP[config.icon];
|
||||||
const showActions = !isReadOnly && !isFilteredEmpty;
|
const showActions = !isReadOnly && !isFilteredEmpty;
|
||||||
const showShortcut = columnId === 'backlog' && addFeatureShortcut && showActions;
|
const showShortcut = columnId === 'backlog' && addFeatureShortcut && showActions;
|
||||||
|
|
||||||
// Minimized state - compact centered indicator
|
|
||||||
if (isMinimized) {
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
onClick={() => setIsMinimized(false)}
|
|
||||||
className={cn(
|
|
||||||
'w-full h-full min-h-[120px] flex-1',
|
|
||||||
'flex items-center justify-center gap-2',
|
|
||||||
'text-muted-foreground/40 hover:text-muted-foreground/60',
|
|
||||||
'cursor-pointer group',
|
|
||||||
'transition-colors duration-200',
|
|
||||||
'animate-in fade-in duration-300'
|
|
||||||
)}
|
|
||||||
data-testid={`empty-state-minimized-${columnId}`}
|
|
||||||
>
|
|
||||||
<Eye className="w-3.5 h-3.5 group-hover:scale-110 transition-transform" />
|
|
||||||
<span className="text-xs font-medium">Show guidance</span>
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Action button handler
|
// Action button handler
|
||||||
const handlePrimaryAction = () => {
|
const handlePrimaryAction = () => {
|
||||||
if (!config.primaryAction) return;
|
if (!config.primaryAction) return;
|
||||||
@@ -108,24 +69,6 @@ export const EmptyStateCard = memo(function EmptyStateCard({
|
|||||||
)}
|
)}
|
||||||
data-testid={`empty-state-card-${columnId}`}
|
data-testid={`empty-state-card-${columnId}`}
|
||||||
>
|
>
|
||||||
{/* Dismiss/Minimize controls - appears on hover */}
|
|
||||||
<div className="absolute top-2 right-2 flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
||||||
<button
|
|
||||||
onClick={() => setIsMinimized(true)}
|
|
||||||
className="p-1 rounded-md text-muted-foreground/30 hover:text-muted-foreground/60 transition-colors"
|
|
||||||
title="Minimize guidance"
|
|
||||||
>
|
|
||||||
<EyeOff className="w-3 h-3" />
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => setIsDismissed(true)}
|
|
||||||
className="p-1 rounded-md text-muted-foreground/30 hover:text-muted-foreground/60 transition-colors"
|
|
||||||
title="Dismiss"
|
|
||||||
>
|
|
||||||
<X className="w-3 h-3" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Icon */}
|
{/* Icon */}
|
||||||
<div className="mb-3 text-muted-foreground/30">
|
<div className="mb-3 text-muted-foreground/30">
|
||||||
<IconComponent className="w-8 h-8" />
|
<IconComponent className="w-8 h-8" />
|
||||||
|
|||||||
@@ -16,10 +16,6 @@ export interface EmptyStateConfig {
|
|||||||
label: string;
|
label: string;
|
||||||
actionType: 'ai-suggest' | 'none';
|
actionType: 'ai-suggest' | 'none';
|
||||||
};
|
};
|
||||||
exampleCard?: {
|
|
||||||
title: string;
|
|
||||||
category: string;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,49 +30,29 @@ export const EMPTY_STATE_CONFIGS: Record<string, EmptyStateConfig> = {
|
|||||||
shortcutHint: 'Press',
|
shortcutHint: 'Press',
|
||||||
primaryAction: {
|
primaryAction: {
|
||||||
label: 'Use AI Suggestions',
|
label: 'Use AI Suggestions',
|
||||||
actionType: 'ai-suggest',
|
actionType: 'none',
|
||||||
},
|
|
||||||
exampleCard: {
|
|
||||||
title: 'User Authentication',
|
|
||||||
category: 'Core Feature',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
in_progress: {
|
in_progress: {
|
||||||
title: 'Nothing in Progress',
|
title: 'Nothing in Progress',
|
||||||
description: 'Drag a feature from the backlog here or click implement to start working on it.',
|
description: 'Drag a feature from the backlog here or click implement to start working on it.',
|
||||||
icon: 'play',
|
icon: 'play',
|
||||||
exampleCard: {
|
|
||||||
title: 'Implementing feature...',
|
|
||||||
category: 'In Development',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
waiting_approval: {
|
waiting_approval: {
|
||||||
title: 'No Items Awaiting Approval',
|
title: 'No Items Awaiting Approval',
|
||||||
description: 'Features will appear here after implementation is complete and need your review.',
|
description: 'Features will appear here after implementation is complete and need your review.',
|
||||||
icon: 'clock',
|
icon: 'clock',
|
||||||
exampleCard: {
|
|
||||||
title: 'Ready for Review',
|
|
||||||
category: 'Completed',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
verified: {
|
verified: {
|
||||||
title: 'No Verified Features',
|
title: 'No Verified Features',
|
||||||
description: 'Approved features will appear here. They can then be completed and archived.',
|
description: 'Approved features will appear here. They can then be completed and archived.',
|
||||||
icon: 'check',
|
icon: 'check',
|
||||||
exampleCard: {
|
|
||||||
title: 'Approved & Ready',
|
|
||||||
category: 'Verified',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
// Pipeline step default configuration
|
// Pipeline step default configuration
|
||||||
pipeline_default: {
|
pipeline_default: {
|
||||||
title: 'Pipeline Step Empty',
|
title: 'Pipeline Step Empty',
|
||||||
description: 'Features will flow through this step during the automated pipeline process.',
|
description: 'Features will flow through this step during the automated pipeline process.',
|
||||||
icon: 'sparkles',
|
icon: 'sparkles',
|
||||||
exampleCard: {
|
|
||||||
title: 'Processing...',
|
|
||||||
category: 'Pipeline',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user