'use client' import { useState, useEffect } from 'react' import { CodeBracketIcon, CheckCircleIcon, XCircleIcon, ArrowPathIcon, ExclamationTriangleIcon, EyeIcon, EyeSlashIcon } from '@heroicons/react/24/outline' interface RepositoryProvider { name: string displayName: string description: string requiresBaseURL: boolean defaultBaseURL?: string } interface RepositoryConfig { provider: string baseURL: string accessToken: string owner: string repository: string } interface ValidationResult { valid: boolean message?: string error?: string } interface RepositoryConfigurationProps { systemInfo: any configData: any onComplete: (data: any) => void onBack?: () => void isCompleted: boolean } export default function RepositoryConfiguration({ systemInfo, configData, onComplete, onBack, isCompleted }: RepositoryConfigurationProps) { const [providers, setProviders] = useState([]) const [config, setConfig] = useState({ provider: '', baseURL: '', accessToken: '', owner: '', repository: '' }) const [validation, setValidation] = useState(null) const [validating, setValidating] = useState(false) const [showToken, setShowToken] = useState(false) const [loadingProviders, setLoadingProviders] = useState(true) // Load existing config from configData if available useEffect(() => { if (configData.repository) { setConfig({ ...configData.repository }) } }, [configData]) // Load supported providers useEffect(() => { loadProviders() }, []) const loadProviders = async () => { try { const response = await fetch('/api/setup/repository/providers') if (response.ok) { const result = await response.json() const providerList = result.providers || [] // Map provider names to full provider objects const providersData: RepositoryProvider[] = providerList.map((name: string) => { switch (name.toLowerCase()) { case 'gitea': return { name: 'gitea', displayName: 'Gitea', description: 'Self-hosted Git service with issue tracking', requiresBaseURL: true, defaultBaseURL: 'http://gitea.local' } case 'github': return { name: 'github', displayName: 'GitHub', description: 'Cloud-based Git repository hosting service', requiresBaseURL: false, defaultBaseURL: 'https://api.github.com' } default: return { name: name.toLowerCase(), displayName: name, description: 'Git repository service', requiresBaseURL: true } } }) setProviders(providersData) // Set default provider if none selected if (!config.provider && providersData.length > 0) { const defaultProvider = providersData.find(p => p.name === 'gitea') || providersData[0] handleProviderChange(defaultProvider.name) } } } catch (error) { console.error('Failed to load providers:', error) } finally { setLoadingProviders(false) } } const handleProviderChange = (provider: string) => { const providerData = providers.find(p => p.name === provider) setConfig(prev => ({ ...prev, provider, baseURL: providerData?.defaultBaseURL || prev.baseURL })) setValidation(null) } const handleInputChange = (field: keyof RepositoryConfig, value: string) => { setConfig(prev => ({ ...prev, [field]: value })) setValidation(null) } const validateRepository = async () => { if (!config.provider || !config.accessToken || !config.owner || !config.repository) { setValidation({ valid: false, error: 'Please fill in all required fields' }) return } setValidating(true) setValidation(null) try { const response = await fetch('/api/setup/repository/validate', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(config) }) const result = await response.json() if (response.ok && result.valid) { setValidation({ valid: true, message: result.message || 'Repository connection successful' }) } else { setValidation({ valid: false, error: result.error || 'Validation failed' }) } } catch (error) { setValidation({ valid: false, error: 'Network error: Unable to validate repository' }) } finally { setValidating(false) } } const handleSubmit = (e: React.FormEvent) => { e.preventDefault() if (validation?.valid) { onComplete({ repository: config }) } else { validateRepository() } } const selectedProvider = providers.find(p => p.name === config.provider) const isFormValid = config.provider && config.accessToken && config.owner && config.repository && (!selectedProvider?.requiresBaseURL || config.baseURL) if (loadingProviders) { return (

Loading repository providers...

) } return (
{/* Repository Provider Selection */}

Repository Provider

{providers.map((provider) => (
handleProviderChange(provider.name)} >
handleProviderChange(provider.name)} className="h-4 w-4 text-bzzz-primary focus:ring-bzzz-primary border-gray-300" />
{provider.displayName}
{provider.description}
))}
{/* Configuration Form */} {config.provider && (
{/* Base URL (for providers that require it) */} {selectedProvider?.requiresBaseURL && (
handleInputChange('baseURL', e.target.value)} placeholder={`e.g., ${selectedProvider.defaultBaseURL || 'https://git.example.com'}`} className="input-field" required />

The base URL for your {selectedProvider.displayName} instance

)} {/* Access Token */}
handleInputChange('accessToken', e.target.value)} placeholder={`Your ${selectedProvider?.displayName} access token`} className="input-field pr-10" required />

{selectedProvider?.name === 'github' ? 'Generate a personal access token with repo and admin:repo_hook permissions' : 'Generate an access token with repository read/write permissions' }

{/* Owner/Organization */}
handleInputChange('owner', e.target.value)} placeholder="username or organization" className="input-field" required />

The username or organization that owns the repository

{/* Repository Name */}
handleInputChange('repository', e.target.value)} placeholder="repository-name" className="input-field" required />

The name of the repository for task management

{/* Validation Section */}

Connection Test

{validation && (
{validation.valid ? ( ) : ( )} {validation.valid ? validation.message : validation.error}
)} {!isFormValid && (

Please fill in all required fields to test the connection

)}
)} {/* Action Buttons */}
{onBack && ( )}
) }