diff --git a/fix-propositions-update-policy.sql b/fix-propositions-update-policy.sql new file mode 100644 index 0000000..046b650 --- /dev/null +++ b/fix-propositions-update-policy.sql @@ -0,0 +1,18 @@ +-- Script pour corriger les politiques RLS manquantes pour les mises à jour +-- À exécuter dans l'interface SQL de Supabase + +-- Ajouter la politique manquante pour les mises à jour des propositions +CREATE POLICY "Allow public update access to propositions" ON propositions FOR UPDATE USING (true); + +-- Ajouter la politique manquante pour les mises à jour des participants +CREATE POLICY "Allow public update access to participants" ON participants FOR UPDATE USING (true); + +-- Vérifier que toutes les politiques sont en place pour les propositions +SELECT schemaname, tablename, policyname, permissive, roles, cmd, qual, with_check +FROM pg_policies +WHERE tablename = 'propositions'; + +-- Vérifier que toutes les politiques sont en place pour les participants +SELECT schemaname, tablename, policyname, permissive, roles, cmd, qual, with_check +FROM pg_policies +WHERE tablename = 'participants'; diff --git a/src/components/AddParticipantModal.tsx b/src/components/AddParticipantModal.tsx index 8a0a590..6433df3 100644 --- a/src/components/AddParticipantModal.tsx +++ b/src/components/AddParticipantModal.tsx @@ -42,9 +42,10 @@ export default function AddParticipantModal({ isOpen, onClose, onSuccess, campai last_name: '', email: '' }); - } catch (err) { - setError('Erreur lors de l\'ajout du participant'); - console.error(err); + } catch (err: any) { + const errorMessage = err?.message || err?.details || 'Erreur lors de l\'ajout du participant'; + setError(`Erreur lors de l'ajout du participant: ${errorMessage}`); + console.error('Erreur lors de l\'ajout du participant:', err); } finally { setLoading(false); } diff --git a/src/components/AddPropositionModal.tsx b/src/components/AddPropositionModal.tsx index f8ebacc..3e574f0 100644 --- a/src/components/AddPropositionModal.tsx +++ b/src/components/AddPropositionModal.tsx @@ -48,9 +48,10 @@ export default function AddPropositionModal({ isOpen, onClose, onSuccess, campai author_last_name: 'admin', author_email: 'admin@example.com' }); - } catch (err) { - setError('Erreur lors de la création de la proposition'); - console.error(err); + } catch (err: any) { + const errorMessage = err?.message || err?.details || 'Erreur lors de la création de la proposition'; + setError(`Erreur lors de la création de la proposition: ${errorMessage}`); + console.error('Erreur lors de la création de la proposition:', err); } finally { setLoading(false); } diff --git a/src/components/DeleteParticipantModal.tsx b/src/components/DeleteParticipantModal.tsx index b3ada79..5d8c94c 100644 --- a/src/components/DeleteParticipantModal.tsx +++ b/src/components/DeleteParticipantModal.tsx @@ -26,9 +26,10 @@ export default function DeleteParticipantModal({ isOpen, onClose, onSuccess, par try { await participantService.delete(participant.id); onSuccess(); - } catch (err) { - setError('Erreur lors de la suppression du participant'); - console.error(err); + } catch (err: any) { + const errorMessage = err?.message || err?.details || 'Erreur lors de la suppression du participant'; + setError(`Erreur lors de la suppression du participant: ${errorMessage}`); + console.error('Erreur lors de la suppression du participant:', err); } finally { setLoading(false); } diff --git a/src/components/DeletePropositionModal.tsx b/src/components/DeletePropositionModal.tsx index de26537..e60fc98 100644 --- a/src/components/DeletePropositionModal.tsx +++ b/src/components/DeletePropositionModal.tsx @@ -26,9 +26,10 @@ export default function DeletePropositionModal({ isOpen, onClose, onSuccess, pro try { await propositionService.delete(proposition.id); onSuccess(); - } catch (err) { - setError('Erreur lors de la suppression de la proposition'); - console.error(err); + } catch (err: any) { + const errorMessage = err?.message || err?.details || 'Erreur lors de la suppression de la proposition'; + setError(`Erreur lors de la suppression de la proposition: ${errorMessage}`); + console.error('Erreur lors de la suppression de la proposition:', err); } finally { setLoading(false); } diff --git a/src/components/EditParticipantModal.tsx b/src/components/EditParticipantModal.tsx index 8bd7b0a..2a67f53 100644 --- a/src/components/EditParticipantModal.tsx +++ b/src/components/EditParticipantModal.tsx @@ -48,9 +48,10 @@ export default function EditParticipantModal({ isOpen, onClose, onSuccess, parti }); onSuccess(); - } catch (err) { - setError('Erreur lors de la modification du participant'); - console.error(err); + } catch (err: any) { + const errorMessage = err?.message || err?.details || 'Erreur lors de la modification du participant'; + setError(`Erreur lors de la modification du participant: ${errorMessage}`); + console.error('Erreur lors de la modification du participant:', err); } finally { setLoading(false); } diff --git a/src/components/EditPropositionModal.tsx b/src/components/EditPropositionModal.tsx index 9770825..37fd05f 100644 --- a/src/components/EditPropositionModal.tsx +++ b/src/components/EditPropositionModal.tsx @@ -55,9 +55,10 @@ export default function EditPropositionModal({ isOpen, onClose, onSuccess, propo }); onSuccess(); - } catch (err) { - setError('Erreur lors de la modification de la proposition'); - console.error(err); + } catch (err: any) { + const errorMessage = err?.message || err?.details || 'Erreur lors de la modification de la proposition'; + setError(`Erreur lors de la modification de la proposition: ${errorMessage}`); + console.error('Erreur lors de la modification de la proposition:', err); } finally { setLoading(false); } diff --git a/src/lib/services.ts b/src/lib/services.ts index 49ead4a..b1b8a07 100644 --- a/src/lib/services.ts +++ b/src/lib/services.ts @@ -107,15 +107,32 @@ export const propositionService = { // eslint-disable-next-line @typescript-eslint/no-explicit-any async update(id: string, updates: any): Promise { - const { data, error } = await supabase - .from('propositions') - .update(updates) - .eq('id', id) - .select() - .single(); - - if (error) throw error; - return data; + try { + // Effectuer la mise à jour directement + const { data, error } = await supabase + .from('propositions') + .update(updates) + .eq('id', id) + .select('*') + .single(); + + if (error) { + console.error('Erreur Supabase lors de la mise à jour:', error); + if (error.code === 'PGRST116') { + throw new Error(`Proposition avec l'ID ${id} non trouvée`); + } + throw new Error(`Erreur lors de la mise à jour: ${error.message || 'Erreur inconnue'}`); + } + + if (!data) { + throw new Error('Aucune donnée retournée après la mise à jour'); + } + + return data; + } catch (error: any) { + console.error('Erreur dans propositionService.update:', error); + throw error; + } }, async delete(id: string): Promise { @@ -155,15 +172,32 @@ export const participantService = { // eslint-disable-next-line @typescript-eslint/no-explicit-any async update(id: string, updates: any): Promise { - const { data, error } = await supabase - .from('participants') - .update(updates) - .eq('id', id) - .select() - .single(); - - if (error) throw error; - return data; + try { + // Effectuer la mise à jour directement + const { data, error } = await supabase + .from('participants') + .update(updates) + .eq('id', id) + .select('*') + .single(); + + if (error) { + console.error('Erreur Supabase lors de la mise à jour du participant:', error); + if (error.code === 'PGRST116') { + throw new Error(`Participant avec l'ID ${id} non trouvé`); + } + throw new Error(`Erreur lors de la mise à jour du participant: ${error.message || 'Erreur inconnue'}`); + } + + if (!data) { + throw new Error('Aucune donnée retournée après la mise à jour du participant'); + } + + return data; + } catch (error: any) { + console.error('Erreur dans participantService.update:', error); + throw error; + } }, async delete(id: string): Promise { diff --git a/supabase-schema.sql b/supabase-schema.sql index bdbc7aa..b14329e 100644 --- a/supabase-schema.sql +++ b/supabase-schema.sql @@ -101,10 +101,12 @@ CREATE POLICY "Allow public delete access to campaigns" ON campaigns FOR DELETE CREATE POLICY "Allow public read access to propositions" ON propositions FOR SELECT USING (true); CREATE POLICY "Allow public insert access to propositions" ON propositions FOR INSERT WITH CHECK (true); +CREATE POLICY "Allow public update access to propositions" ON propositions FOR UPDATE USING (true); CREATE POLICY "Allow public delete access to propositions" ON propositions FOR DELETE USING (true); CREATE POLICY "Allow public read access to participants" ON participants FOR SELECT USING (true); CREATE POLICY "Allow public insert access to participants" ON participants FOR INSERT WITH CHECK (true); +CREATE POLICY "Allow public update access to participants" ON participants FOR UPDATE USING (true); CREATE POLICY "Allow public delete access to participants" ON participants FOR DELETE USING (true); CREATE POLICY "Allow public read access to votes" ON votes FOR SELECT USING (true);