Initial commit: Brachnha Insight project setup
- Next.js 14+ with App Router and TypeScript - Tailwind CSS and ShadCN UI styling - Zustand state management - Dexie.js for IndexedDB (local-first data) - Auth.js v5 for authentication - BMAD framework integration Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
95
src/components/features/settings/connection-status.tsx
Normal file
95
src/components/features/settings/connection-status.tsx
Normal file
@@ -0,0 +1,95 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from 'react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { SettingsService } from '@/services/settings-service';
|
||||
import { useApiKey } from '@/store/use-settings';
|
||||
|
||||
/**
|
||||
* Connection Validation States
|
||||
*/
|
||||
type ValidationStatus = 'idle' | 'testing' | 'success' | 'error';
|
||||
|
||||
/**
|
||||
* Connection Status Component (Story 4.2 Enhanced)
|
||||
*
|
||||
* Displays API connection validation status with detailed error messages
|
||||
* and retry capability.
|
||||
*/
|
||||
export function ConnectionStatus() {
|
||||
const apiKey = useApiKey();
|
||||
const [status, setStatus] = useState<ValidationStatus>('idle');
|
||||
const [errorMessage, setErrorMessage] = useState<string>('');
|
||||
|
||||
const handleTest = async () => {
|
||||
if (!apiKey) return;
|
||||
|
||||
setStatus('testing');
|
||||
setErrorMessage('');
|
||||
|
||||
try {
|
||||
// Use SettingsService for proper Logic Sandwich pattern
|
||||
const result = await SettingsService.validateProviderConnection();
|
||||
|
||||
if (result.isValid) {
|
||||
setStatus('success');
|
||||
} else {
|
||||
setStatus('error');
|
||||
setErrorMessage(result.error || 'Connection failed');
|
||||
}
|
||||
} catch (error) {
|
||||
setStatus('error');
|
||||
setErrorMessage(error instanceof Error ? error.message : 'Connection failed');
|
||||
}
|
||||
};
|
||||
|
||||
if (!apiKey) return null;
|
||||
|
||||
return (
|
||||
<div className="space-y-2 mt-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={handleTest}
|
||||
disabled={status === 'testing'}
|
||||
>
|
||||
{status === 'testing' ? 'Testing...' : 'Test Connection'}
|
||||
</Button>
|
||||
|
||||
{status === 'success' && (
|
||||
<span className="text-green-600 font-medium flex items-center gap-1">
|
||||
<span className="inline-block w-2 h-2 bg-green-500 rounded-full" />
|
||||
Connected ✅
|
||||
</span>
|
||||
)}
|
||||
|
||||
{status === 'error' && (
|
||||
<span className="text-red-600 font-medium flex items-center gap-1">
|
||||
<span className="inline-block w-2 h-2 bg-red-500 rounded-full" />
|
||||
Connection Failed ❌
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{status === 'error' && errorMessage && (
|
||||
<div className="space-y-2">
|
||||
<p className="text-sm text-red-600">{errorMessage}</p>
|
||||
|
||||
{/* Retry hint for network errors */}
|
||||
{errorMessage.toLowerCase().includes('network') && (
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Tip: Network errors can be temporary. Try again in a moment.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Success message with auto-hide hint */}
|
||||
{status === 'success' && (
|
||||
<p className="text-xs text-green-600">
|
||||
Your API credentials are working correctly!
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user