| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- 'use client';
- 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>
- );
- }
|