'use client'; import { useState, useEffect } from 'react'; import { useRouter } from 'next/navigation'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Alert, AlertDescription } from '@/components/ui/alert'; import { Loader2, CheckCircle, AlertCircle, Database, Key, User, Shield } from 'lucide-react'; import SqlSchemaDisplay from '@/components/SqlSchemaDisplay'; interface SetupStep { id: string; title: string; description: string; status: 'pending' | 'current' | 'completed' | 'error'; icon: React.ReactNode; } export default function SetupPage() { const router = useRouter(); const [currentStep, setCurrentStep] = useState(0); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const [success, setSuccess] = useState(false); const [formData, setFormData] = useState({ supabaseUrl: '', supabaseAnonKey: '', supabaseServiceKey: '', adminEmail: '', adminPassword: '', adminConfirmPassword: '' }); const steps: SetupStep[] = [ { id: 'supabase-project', title: 'Créer un projet Supabase', description: 'Créez un nouveau projet sur Supabase.com', status: 'pending', icon: }, { id: 'supabase-keys', title: 'Récupérer les clés Supabase', description: 'Copiez les clés de votre projet', status: 'pending', icon: }, { id: 'database-setup', title: 'Configurer la base de données', description: 'Créer les tables et politiques de sécurité', status: 'pending', icon: }, { id: 'admin-creation', title: 'Créer l\'administrateur', description: 'Créer le premier compte administrateur', status: 'pending', icon: }, { id: 'security-setup', title: 'Configurer la sécurité', description: 'Activer les politiques RLS', status: 'pending', icon: } ]; useEffect(() => { // Vérifier si Supabase est déjà configuré checkExistingSetup(); }, []); const checkExistingSetup = async () => { const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; if (supabaseUrl && supabaseAnonKey && supabaseUrl !== 'https://placeholder.supabase.co') { // Supabase est déjà configuré, rediriger vers l'accueil router.push('/'); } }; const updateStepStatus = (stepIndex: number, status: SetupStep['status']) => { steps[stepIndex].status = status; }; const handleInputChange = (field: string, value: string) => { setFormData(prev => ({ ...prev, [field]: value })); }; const validateSupabaseKeys = () => { if (!formData.supabaseUrl || !formData.supabaseAnonKey || !formData.supabaseServiceKey) { setError('Veuillez remplir tous les champs Supabase'); return false; } return true; }; const validateAdminCredentials = () => { if (!formData.adminEmail || !formData.adminPassword || !formData.adminConfirmPassword) { setError('Veuillez remplir tous les champs administrateur'); return false; } if (formData.adminPassword !== formData.adminConfirmPassword) { setError('Les mots de passe ne correspondent pas'); return false; } if (formData.adminPassword.length < 6) { setError('Le mot de passe doit contenir au moins 6 caractères'); return false; } return true; }; const handleNextStep = async () => { setError(''); if (currentStep === 1) { // Validation des clés Supabase if (!validateSupabaseKeys()) return; } if (currentStep === 3) { // Validation des credentials admin if (!validateAdminCredentials()) return; } if (currentStep === steps.length - 1) { // Dernière étape : finaliser la configuration await finalizeSetup(); return; } setCurrentStep(prev => prev + 1); }; const handlePreviousStep = () => { setCurrentStep(prev => Math.max(0, prev - 1)); }; const finalizeSetup = async () => { setLoading(true); setError(''); try { // Ici nous appellerons l'API pour finaliser la configuration const response = await fetch('/api/setup/finalize', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(formData), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Erreur lors de la configuration'); } setSuccess(true); setTimeout(() => { router.push('/admin'); }, 2000); } catch (error: any) { setError(error.message || 'Erreur lors de la configuration'); } finally { setLoading(false); } }; const renderStepContent = () => { switch (currentStep) { case 0: return (
Vous devez créer un projet Supabase pour utiliser cette application.

Étapes pour créer un projet Supabase :

  1. Allez sur supabase.com
  2. Cliquez sur "Start your project"
  3. Connectez-vous ou créez un compte
  4. Cliquez sur "New project"
  5. Choisissez votre organisation
  6. Donnez un nom à votre projet (ex: "mes-budgets-participatifs")
  7. Créez un mot de passe pour la base de données
  8. Choisissez une région proche de vous
  9. Cliquez sur "Create new project"
  10. Attendez que le projet soit créé (2-3 minutes)

Note : Une fois votre projet créé, vous aurez besoin de l'URL et des clés API que nous configurerons dans l'étape suivante.

); case 1: return (
Récupérez les clés de votre projet Supabase dans les paramètres.

Comment récupérer vos clés :

  1. Dans votre projet Supabase, allez dans "Settings" (⚙️)
  2. Cliquez sur "API" dans le menu de gauche
  3. Copiez l'URL du projet (Project URL)
  4. Copiez la clé anon/public (anon public key)
  5. Copiez la clé service_role (service_role key)
handleInputChange('supabaseUrl', e.target.value)} />
handleInputChange('supabaseAnonKey', e.target.value)} />
handleInputChange('supabaseServiceKey', e.target.value)} />
); case 2: return (
Vous devez créer les tables de base de données dans votre projet Supabase. L'assistant nettoiera automatiquement les données existantes.

Comment créer les tables :

  1. Dans votre projet Supabase, allez dans "SQL Editor"
  2. Cliquez sur "New query"
  3. Copiez le schéma SQL ci-dessous
  4. Collez-le dans l'éditeur SQL
  5. Cliquez sur "Run" pour exécuter le script
  6. Vérifiez que les tables sont créées dans "Table Editor"

Ce qui va être créé :

  • Tables : campaigns, propositions, participants, votes, settings, admin_users
  • Politiques de sécurité (RLS)
  • Fonctions utilitaires
  • Index et contraintes

Info : L'assistant nettoiera automatiquement toutes les données existantes avant de créer le nouvel administrateur.

Important : Cette étape est manuelle. Vous devez exécuter le script SQL dans votre projet Supabase avant de continuer.

); case 3: return (
Créez le premier compte administrateur pour accéder à l'interface d'administration.
handleInputChange('adminEmail', e.target.value)} />
handleInputChange('adminPassword', e.target.value)} />
handleInputChange('adminConfirmPassword', e.target.value)} />

Important : Gardez ces identifiants en sécurité. Vous en aurez besoin pour accéder à l'administration.

); case 4: return (
Configuration finale de la sécurité et activation du mode production.

Configuration finale :

  • Activation des politiques RLS (Row Level Security)
  • Configuration des permissions utilisateur
  • Création des variables d'environnement
  • Test de connexion à la base de données
  • Activation du mode production

Prêt ! Une fois cette étape terminée, vous pourrez accéder à l'interface d'administration et commencer à créer vos campagnes.

); default: return null; } }; if (success) { return (
Configuration terminée ! Votre application est maintenant configurée et prête à être utilisée.

Redirection vers l'administration...

); } return (

Configuration de Mes Budgets Participatifs

Assistant de configuration pour votre nouvelle installation

{/* Étapes */}
{steps.map((step, index) => (
{step.status === 'completed' ? ( ) : ( step.icon )}
{index < steps.length - 1 && (
)}
))}
{steps.map((step) => (

{step.title}

))}
{/* Contenu de l'étape */} {steps[currentStep].icon} {steps[currentStep].title} {steps[currentStep].description} {error && ( {error} )} {renderStepContent()} {/* Boutons de navigation */}
); }