mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-01 15:03:57 +08:00
feat(a2ui): Implement A2UI backend with question handling and WebSocket support
- Added A2UITypes for defining question structures and answers. - Created A2UIWebSocketHandler for managing WebSocket connections and message handling. - Developed ask-question tool for interactive user questions via A2UI. - Introduced platformUtils for platform detection and shell command handling. - Centralized TypeScript types in index.ts for better organization. - Implemented compatibility checks for hook templates based on platform requirements.
This commit is contained in:
89
ccw/frontend/src/components/shared/PromptStats.tsx
Normal file
89
ccw/frontend/src/components/shared/PromptStats.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
// ========================================
|
||||
// PromptStats Component
|
||||
// ========================================
|
||||
// Statistics display for prompt history
|
||||
|
||||
import * as React from 'react';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { StatCard } from '@/components/shared/StatCard';
|
||||
import { MessageSquare, FileType, Hash } from 'lucide-react';
|
||||
|
||||
export interface PromptStatsProps {
|
||||
/** Total number of prompts */
|
||||
totalCount: number;
|
||||
/** Average prompt length in characters */
|
||||
avgLength: number;
|
||||
/** Most common intent/category */
|
||||
topIntent: string | null;
|
||||
/** Loading state */
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* PromptStats component - displays prompt history statistics
|
||||
*
|
||||
* Shows three key metrics:
|
||||
* - Total prompts: overall count of stored prompts
|
||||
* - Average length: mean character count across all prompts
|
||||
* - Top intent: most frequently used category
|
||||
*/
|
||||
export function PromptStats({
|
||||
totalCount,
|
||||
avgLength,
|
||||
topIntent,
|
||||
isLoading = false,
|
||||
}: PromptStatsProps) {
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
// Format average length for display
|
||||
const formatLength = (length: number): string => {
|
||||
if (length >= 1000) {
|
||||
return `${(length / 1000).toFixed(1)}k`;
|
||||
}
|
||||
return length.toString();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="grid gap-4 grid-cols-1 md:grid-cols-3">
|
||||
<StatCard
|
||||
title={formatMessage({ id: 'prompts.stats.totalCount' })}
|
||||
value={totalCount}
|
||||
icon={MessageSquare}
|
||||
variant="primary"
|
||||
isLoading={isLoading}
|
||||
description={formatMessage({ id: 'prompts.stats.totalCountDesc' })}
|
||||
/>
|
||||
<StatCard
|
||||
title={formatMessage({ id: 'prompts.stats.avgLength' })}
|
||||
value={formatLength(avgLength)}
|
||||
icon={FileType}
|
||||
variant="info"
|
||||
isLoading={isLoading}
|
||||
description={formatMessage({ id: 'prompts.stats.avgLengthDesc' })}
|
||||
/>
|
||||
<StatCard
|
||||
title={formatMessage({ id: 'prompts.stats.topIntent' })}
|
||||
value={topIntent || formatMessage({ id: 'prompts.stats.noIntent' })}
|
||||
icon={Hash}
|
||||
variant="success"
|
||||
isLoading={isLoading}
|
||||
description={formatMessage({ id: 'prompts.stats.topIntentDesc' })}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Skeleton loader for PromptStats
|
||||
*/
|
||||
export function PromptStatsSkeleton() {
|
||||
return (
|
||||
<div className="grid gap-4 grid-cols-1 md:grid-cols-3">
|
||||
<StatCardSkeleton />
|
||||
<StatCardSkeleton />
|
||||
<StatCardSkeleton />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default PromptStats;
|
||||
Reference in New Issue
Block a user