OpenMAIC-React / src /components /settings /provider-list.tsx
muthuk1's picture
Convert OpenMAIC from Next.js to React (Vite)
f56a29b verified
import { Button } from '@/components/ui/button';
import { Box, Plus } from 'lucide-react';
import { cn } from '@/lib/utils';
import { useI18n } from '@/lib/hooks/use-i18n';
import type { ProviderId, ProviderConfig } from '@/lib/ai/providers';
import { MONO_LOGO_PROVIDERS } from '@/lib/ai/providers';
interface ProviderWithServerInfo extends ProviderConfig {
isServerConfigured?: boolean;
}
interface ProviderListProps {
providers: ProviderWithServerInfo[];
selectedProviderId: ProviderId;
onSelect: (providerId: ProviderId) => void;
onAddProvider: () => void;
width?: number;
}
export function ProviderList({
providers,
selectedProviderId,
onSelect,
onAddProvider,
width,
}: ProviderListProps) {
const { t } = useI18n();
// Helper function to get translated provider name
const getProviderDisplayName = (provider: ProviderConfig) => {
const translationKey = `settings.providerNames.${provider.id}`;
const translated = t(translationKey);
// If translation exists (not equal to key), use it; otherwise fallback to provider.name
return translated !== translationKey ? translated : provider.name;
};
return (
<div className="flex-shrink-0 bg-background flex flex-col" style={{ width: width ?? 192 }}>
<div className="flex-1 overflow-y-auto p-3 space-y-1.5">
{providers.map((provider) => (
<button
key={provider.id}
onClick={() => onSelect(provider.id)}
className={cn(
'w-full flex items-center gap-2.5 px-3 py-2.5 rounded-lg transition-all border text-left',
selectedProviderId === provider.id
? 'bg-primary/5 border-primary/50 shadow-sm'
: 'border-transparent hover:bg-muted/50',
)}
>
{provider.icon ? (
<img
src={provider.icon}
alt={getProviderDisplayName(provider)}
className={cn(
'w-5 h-5 rounded',
MONO_LOGO_PROVIDERS.has(provider.id) && 'dark:invert',
)}
onError={(e) => {
(e.target as HTMLImageElement).style.display = 'none';
}}
/>
) : (
<Box className="h-5 w-5 text-muted-foreground" />
)}
<span className="font-medium text-sm flex-1 truncate">
{getProviderDisplayName(provider)}
</span>
{provider.isServerConfigured && (
<span className="text-[10px] px-1 py-0 h-4 leading-4 rounded shrink-0 bg-muted text-muted-foreground">
{t('settings.serverConfigured')}
</span>
)}
</button>
))}
</div>
{/* Add Provider Button */}
<div className="p-3 border-t">
<Button variant="outline" size="sm" className="w-full gap-1.5" onClick={onAddProvider}>
<Plus className="h-3.5 w-3.5" />
{t('settings.addProviderButton')}
</Button>
</div>
</div>
);
}