| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- 'use client';
- import React from 'react';
- import { Badge } from '@/components/ui/badge';
- import { Button } from '@/components/ui/button';
- import {
- CheckCircle2,
- AlertCircle,
- XCircle,
- Zap,
- RotateCcw,
- Info,
- AlertTriangle
- } from 'lucide-react';
- import { cn } from '@/lib/utils';
- interface ModelSelectionIndicatorProps {
- modelName: string | null;
- isAutoSelected: boolean;
- isUserOverride: boolean;
- isLoaded?: boolean;
- onClearOverride?: () => void;
- onRevertToAuto?: () => void;
- className?: string;
- }
- export function ModelSelectionIndicator({
- modelName,
- isAutoSelected,
- isUserOverride,
- isLoaded = false,
- onClearOverride,
- onRevertToAuto,
- className
- }: ModelSelectionIndicatorProps) {
- if (!modelName) {
- return (
- <div className={cn("flex items-center gap-2 text-sm text-muted-foreground", className)}>
- <XCircle className="h-4 w-4" />
- <span>No model selected</span>
- </div>
- );
- }
- const getIndicatorColor = () => {
- if (isUserOverride) {
- return 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200';
- }
- if (isAutoSelected) {
- return 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200';
- }
- return 'bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200';
- };
- const getIndicatorIcon = () => {
- if (isUserOverride) {
- return <CheckCircle2 className="h-3 w-3" />;
- }
- if (isAutoSelected) {
- return <Zap className="h-3 w-3" />;
- }
- return <Info className="h-3 w-3" />;
- };
- const getIndicatorText = () => {
- if (isUserOverride) {
- return 'Manual';
- }
- if (isAutoSelected) {
- return 'Auto';
- }
- return 'Selected';
- };
- return (
- <div className={cn("flex items-center gap-2", className)}>
- <Badge variant="secondary" className={getIndicatorColor()}>
- {getIndicatorIcon()}
- <span className="ml-1">{getIndicatorText()}</span>
- </Badge>
-
- <span className={cn(
- "text-sm",
- isLoaded ? "text-green-600 dark:text-green-400" : "text-muted-foreground"
- )}>
- {modelName}
- </span>
- {isUserOverride && onClearOverride && (
- <Button
- variant="ghost"
- size="sm"
- onClick={onClearOverride}
- className="h-6 w-6 p-0"
- title="Clear manual selection"
- >
- <RotateCcw className="h-3 w-3" />
- </Button>
- )}
- {isUserOverride && onRevertToAuto && (
- <Button
- variant="ghost"
- size="sm"
- onClick={onRevertToAuto}
- className="h-6 w-6 p-0"
- title="Revert to auto-selected model"
- >
- <Zap className="h-3 w-3" />
- </Button>
- )}
- </div>
- );
- }
- interface ModelSelectionWarningProps {
- warnings: string[];
- errors: string[];
- onClearWarnings?: () => void;
- className?: string;
- }
- export function ModelSelectionWarning({
- warnings,
- errors,
- onClearWarnings,
- className
- }: ModelSelectionWarningProps) {
- if (warnings.length === 0 && errors.length === 0) {
- return null;
- }
- return (
- <div className={cn("space-y-2", className)}>
- {errors.map((error, index) => (
- <div key={index} className="flex items-start gap-2 p-2 rounded-md bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-800">
- <XCircle className="h-4 w-4 text-red-500 mt-0.5 flex-shrink-0" />
- <p className="text-sm text-red-700 dark:text-red-300">{error}</p>
- </div>
- ))}
-
- {warnings.map((warning, index) => (
- <div key={index} className="flex items-start gap-2 p-2 rounded-md bg-yellow-50 dark:bg-yellow-950/20 border border-yellow-200 dark:border-yellow-800">
- <AlertTriangle className="h-4 w-4 text-yellow-500 mt-0.5 flex-shrink-0" />
- <p className="text-sm text-yellow-700 dark:text-yellow-300">{warning}</p>
- </div>
- ))}
- {onClearWarnings && warnings.length > 0 && (
- <Button
- variant="ghost"
- size="sm"
- onClick={onClearWarnings}
- className="text-xs"
- >
- Clear warnings
- </Button>
- )}
- </div>
- );
- }
- interface AutoSelectionStatusProps {
- isAutoSelecting: boolean;
- hasAutoSelection: boolean;
- onRetryAutoSelection?: () => void;
- className?: string;
- }
- export function AutoSelectionStatus({
- isAutoSelecting,
- hasAutoSelection,
- onRetryAutoSelection,
- className
- }: AutoSelectionStatusProps) {
- if (isAutoSelecting) {
- return (
- <div className={cn("flex items-center gap-2 text-sm text-blue-600 dark:text-blue-400", className)}>
- <div className="animate-spin">
- <Zap className="h-4 w-4" />
- </div>
- <span>Auto-selecting models...</span>
- </div>
- );
- }
- if (!hasAutoSelection) {
- return (
- <div className={cn("flex items-center gap-2 text-sm text-muted-foreground", className)}>
- <AlertCircle className="h-4 w-4" />
- <span>No automatic selection available</span>
- {onRetryAutoSelection && (
- <Button
- variant="ghost"
- size="sm"
- onClick={onRetryAutoSelection}
- className="h-6 px-2 text-xs"
- >
- Retry
- </Button>
- )}
- </div>
- );
- }
- return (
- <div className={cn("flex items-center gap-2 text-sm text-green-600 dark:text-green-400", className)}>
- <CheckCircle2 className="h-4 w-4" />
- <span>Models auto-selected</span>
- </div>
- );
- }
|