diff --git a/web-app/src/containers/ApiKeyInput.tsx b/web-app/src/containers/ApiKeyInput.tsx index 394df5696..b3dc51b3f 100644 --- a/web-app/src/containers/ApiKeyInput.tsx +++ b/web-app/src/containers/ApiKeyInput.tsx @@ -3,15 +3,18 @@ import { useLocalApiServer } from '@/hooks/useLocalApiServer' import { useState, useEffect, useCallback } from 'react' import { Eye, EyeOff } from 'lucide-react' import { useTranslation } from '@/i18n/react-i18next-compat' +import { cn } from '@/lib/utils' interface ApiKeyInputProps { showError?: boolean onValidationChange?: (isValid: boolean) => void + isServerRunning?: boolean } export function ApiKeyInput({ showError = false, onValidationChange, + isServerRunning, }: ApiKeyInputProps) { const { apiKey, setApiKey } = useLocalApiServer() const [inputValue, setInputValue] = useState(apiKey.toString()) @@ -19,16 +22,19 @@ export function ApiKeyInput({ const [error, setError] = useState('') const { t } = useTranslation() - const validateApiKey = useCallback((value: string) => { - if (!value || value.trim().length === 0) { - setError(t('common:apiKeyRequired')) - onValidationChange?.(false) - return false - } - setError('') - onValidationChange?.(true) - return true - }, [onValidationChange, t]) + const validateApiKey = useCallback( + (value: string) => { + if (!value || value.trim().length === 0) { + setError(t('common:apiKeyRequired')) + onValidationChange?.(false) + return false + } + setError('') + onValidationChange?.(true) + return true + }, + [onValidationChange, t] + ) useEffect(() => { if (showError) { @@ -64,11 +70,12 @@ export function ApiKeyInput({ value={inputValue} onChange={handleChange} onBlur={handleBlur} - className={`w-full text-sm pr-10 ${ - hasError - ? 'border-1 border-destructive focus:border-destructive focus:ring-destructive' - : '' - }`} + className={cn( + 'w-full text-sm pr-10', + hasError && + 'border-1 border-destructive focus:border-destructive focus:ring-destructive', + isServerRunning && 'opacity-50 pointer-events-none' + )} placeholder={t('common:enterApiKey')} />
diff --git a/web-app/src/containers/ApiPrefixInput.tsx b/web-app/src/containers/ApiPrefixInput.tsx index ff728f96d..7db60efdb 100644 --- a/web-app/src/containers/ApiPrefixInput.tsx +++ b/web-app/src/containers/ApiPrefixInput.tsx @@ -1,8 +1,13 @@ import { Input } from '@/components/ui/input' import { useLocalApiServer } from '@/hooks/useLocalApiServer' +import { cn } from '@/lib/utils' import { useState } from 'react' -export function ApiPrefixInput() { +export function ApiPrefixInput({ + isServerRunning, +}: { + isServerRunning?: boolean +}) { const { apiPrefix, setApiPrefix } = useLocalApiServer() const [inputValue, setInputValue] = useState(apiPrefix) @@ -27,7 +32,10 @@ export function ApiPrefixInput() { value={inputValue} onChange={handleChange} onBlur={handleBlur} - className="w-24 h-8 text-sm" + className={cn( + 'w-24 h-8 text-sm', + isServerRunning && 'opacity-50 pointer-events-none' + )} placeholder="/v1" /> ) diff --git a/web-app/src/containers/PortInput.tsx b/web-app/src/containers/PortInput.tsx index 2bf783908..2235a9ef7 100644 --- a/web-app/src/containers/PortInput.tsx +++ b/web-app/src/containers/PortInput.tsx @@ -1,8 +1,9 @@ import { Input } from '@/components/ui/input' import { useLocalApiServer } from '@/hooks/useLocalApiServer' +import { cn } from '@/lib/utils' import { useState } from 'react' -export function PortInput() { +export function PortInput({ isServerRunning }: { isServerRunning?: boolean }) { const { serverPort, setServerPort } = useLocalApiServer() const [inputValue, setInputValue] = useState(serverPort.toString()) @@ -29,7 +30,10 @@ export function PortInput() { value={inputValue} onChange={handleChange} onBlur={handleBlur} - className="w-24 h-8 text-sm" + className={cn( + 'w-24 h-8 text-sm', + isServerRunning && 'opacity-50 pointer-events-none' + )} /> ) } diff --git a/web-app/src/containers/ServerHostSwitcher.tsx b/web-app/src/containers/ServerHostSwitcher.tsx index 1643d71ff..ee05908ab 100644 --- a/web-app/src/containers/ServerHostSwitcher.tsx +++ b/web-app/src/containers/ServerHostSwitcher.tsx @@ -4,6 +4,7 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' + import { useLocalApiServer } from '@/hooks/useLocalApiServer' import { cn } from '@/lib/utils' @@ -12,12 +13,19 @@ const hostOptions = [ { value: '0.0.0.0', label: '0.0.0.0' }, ] -export function ServerHostSwitcher() { +export function ServerHostSwitcher({ + isServerRunning, +}: { + isServerRunning?: boolean +}) { const { serverHost, setServerHost } = useLocalApiServer() return ( - + ) } diff --git a/web-app/src/routes/settings/local-api-server.tsx b/web-app/src/routes/settings/local-api-server.tsx index 8b426ddf2..319cf5709 100644 --- a/web-app/src/routes/settings/local-api-server.tsx +++ b/web-app/src/routes/settings/local-api-server.tsx @@ -45,7 +45,8 @@ function LocalAPIServer() { } = useLocalApiServer() const { serverStatus, setServerStatus } = useAppState() - const { selectedModel, selectedProvider, getProviderByName } = useModelProvider() + const { selectedModel, selectedProvider, getProviderByName } = + useModelProvider() const [showApiKeyError, setShowApiKeyError] = useState(false) const [isApiKeyEmpty, setIsApiKeyEmpty] = useState( !apiKey || apiKey.toString().trim().length === 0 @@ -293,38 +294,31 @@ function LocalAPIServer() { } + actions={ + + } /> } + actions={} /> } + actions={} /> @@ -334,11 +328,12 @@ function LocalAPIServer() { title={t('settings:localApiServer.trustedHosts')} description={t('settings:localApiServer.trustedHostsDesc')} className={cn( - 'flex-col sm:flex-row items-start sm:items-center sm:justify-between gap-y-2', - isServerRunning && 'opacity-50 pointer-events-none' + 'flex-col sm:flex-row items-start sm:items-center sm:justify-between gap-y-2' )} classNameWrapperAction="w-full sm:w-auto" - actions={} + actions={ + + } />