'use client'; import { useState, useEffect } from 'react'; import { Button } from '@/components/ui/Button'; import { Badge } from '@/components/ui/Badge'; import { useJiraConfig } from '@/hooks/useJiraConfig'; import { jiraConfigClient } from '@/clients/jira-config-client'; export function JiraConfigForm() { const { config, isLoading: configLoading, saveConfig, deleteConfig } = useJiraConfig(); const [formData, setFormData] = useState({ baseUrl: '', email: '', apiToken: '', projectKey: '', ignoredProjects: [] as string[] }); const [isSubmitting, setIsSubmitting] = useState(false); const [isValidating, setIsValidating] = useState(false); const [validationResult, setValidationResult] = useState<{ type: 'success' | 'error', text: string } | null>(null); const [message, setMessage] = useState<{ type: 'success' | 'error', text: string } | null>(null); // Charger les données existantes dans le formulaire useEffect(() => { if (config) { setFormData({ baseUrl: config.baseUrl || '', email: config.email || '', apiToken: config.apiToken || '', projectKey: config.projectKey || '', ignoredProjects: config.ignoredProjects || [] }); } }, [config]); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setIsSubmitting(true); setMessage(null); try { const result = await saveConfig(formData); if (result.success) { setMessage({ type: 'success', text: result.message }); } else { setMessage({ type: 'error', text: result.message }); } } catch (error) { setMessage({ type: 'error', text: error instanceof Error ? error.message : 'Erreur lors de la sauvegarde de la configuration' }); } finally { setIsSubmitting(false); } }; const handleDelete = async () => { if (!confirm('Êtes-vous sûr de vouloir supprimer la configuration Jira ?')) { return; } setIsSubmitting(true); setMessage(null); try { const result = await deleteConfig(); if (result.success) { setFormData({ baseUrl: '', email: '', apiToken: '', projectKey: '', ignoredProjects: [] }); setMessage({ type: 'success', text: result.message }); } else { setMessage({ type: 'error', text: result.message }); } } catch (error) { setMessage({ type: 'error', text: error instanceof Error ? error.message : 'Erreur lors de la suppression de la configuration' }); } finally { setIsSubmitting(false); } }; const handleValidateProject = async () => { if (!formData.projectKey.trim()) { setValidationResult({ type: 'error', text: 'Veuillez saisir une clé de projet' }); return; } setIsValidating(true); setValidationResult(null); try { const result = await jiraConfigClient.validateProject(formData.projectKey); if (result.success && result.exists) { setValidationResult({ type: 'success', text: `✓ Projet trouvé : ${result.projectName}` }); } else { setValidationResult({ type: 'error', text: result.error || result.message }); } } catch (error) { setValidationResult({ type: 'error', text: error instanceof Error ? error.message : 'Erreur lors de la validation' }); } finally { setIsValidating(false); } }; const isJiraConfigured = config?.enabled && (config?.baseUrl || config?.email); const isLoading = configLoading || isSubmitting; return (
{/* Statut actuel */}

Statut de l'intégration

{isJiraConfigured ? 'Jira est configuré et prêt à être utilisé' : 'Jira n\'est pas configuré' }

{isJiraConfigured ? '✓ Configuré' : '✗ Non configuré'}
{isJiraConfigured && (

Configuration actuelle

URL de base:{' '} {config?.baseUrl || 'Non définie'}
Email:{' '} {config?.email || 'Non défini'}
Token API:{' '} {config?.apiToken ? '••••••••' : 'Non défini'}
Projet surveillé:{' '} {config?.projectKey || 'Non défini'}
Projets ignorés:{' '} {config?.ignoredProjects && config.ignoredProjects.length > 0 ? (
{config.ignoredProjects.map(project => ( {project} ))}
) : ( Aucun )}
)} {/* Formulaire de configuration */}
setFormData(prev => ({ ...prev, baseUrl: e.target.value }))} placeholder="https://votre-domaine.atlassian.net" className="w-full px-3 py-2 border border-[var(--border)] rounded bg-[var(--background)] text-[var(--foreground)] focus:outline-none focus:ring-2 focus:ring-[var(--primary)] focus:border-transparent" required />

L'URL de votre instance Jira Cloud (ex: https://monentreprise.atlassian.net)

setFormData(prev => ({ ...prev, email: e.target.value }))} placeholder="votre-email@exemple.com" className="w-full px-3 py-2 border border-[var(--border)] rounded bg-[var(--background)] text-[var(--foreground)] focus:outline-none focus:ring-2 focus:ring-[var(--primary)] focus:border-transparent" required />

L'email de votre compte Jira

setFormData(prev => ({ ...prev, apiToken: e.target.value }))} placeholder="Votre token API Jira" className="w-full px-3 py-2 border border-[var(--border)] rounded bg-[var(--background)] text-[var(--foreground)] focus:outline-none focus:ring-2 focus:ring-[var(--primary)] focus:border-transparent" required />

Créez un token API depuis{' '} votre profil Atlassian

{ setFormData(prev => ({ ...prev, projectKey: e.target.value.trim().toUpperCase() })); setValidationResult(null); // Reset validation when input changes }} placeholder="MYTEAM" className="flex-1 px-3 py-2 border border-[var(--border)] rounded bg-[var(--background)] text-[var(--foreground)] focus:outline-none focus:ring-2 focus:ring-[var(--primary)] focus:border-transparent" />
{/* Résultat de la validation */} {validationResult && (
{validationResult.text}
)}

Clé du projet pour les analytics d'équipe (ex: MYTEAM, DEV, PROD). Laissez vide pour désactiver la surveillance d'équipe.

{ const projects = e.target.value .split(',') .map(p => p.trim().toUpperCase()) .filter(p => p.length > 0); setFormData(prev => ({ ...prev, ignoredProjects: projects })); }} placeholder="DEMO, TEST, SANDBOX" className="w-full px-3 py-2 border border-[var(--border)] rounded bg-[var(--background)] text-[var(--foreground)] focus:outline-none focus:ring-2 focus:ring-[var(--primary)] focus:border-transparent" />

Liste des clés de projets à ignorer lors de la synchronisation, séparées par des virgules (ex: DEMO, TEST, SANDBOX). Ces projets ne seront pas synchronisés vers TowerControl.

{formData.ignoredProjects.length > 0 && (
Projets qui seront ignorés: {formData.ignoredProjects.map(project => ( {project} ))}
)}
{isJiraConfigured && ( )}
{message && (
{message.text}
)} {/* Instructions */}

💡 Instructions de configuration

1. URL de base: Votre domaine Jira Cloud (ex: https://monentreprise.atlassian.net)

2. Email: L'email de votre compte Jira/Atlassian

3. Token API: Créez un token depuis votre profil Atlassian :

  • Allez sur id.atlassian.com
  • Cliquez sur "Create API token"
  • Donnez un nom descriptif (ex: "TowerControl")
  • Copiez le token généré

Note: Ces variables doivent être configurées dans l'environnement du serveur (JIRA_BASE_URL, JIRA_EMAIL, JIRA_API_TOKEN)

); }