fix: Corriger logos cassés dans PDFs PDFMonkey

- Conserver data URI complète (data:image/png;base64,...) lors de l'upload
- Ajout script migration SQL pour logos existants
- Compatible avec affichage et génération PDF PDFMonkey
This commit is contained in:
odentas 2025-11-27 14:09:16 +01:00
parent ce46db63af
commit 8edb624330
3 changed files with 176 additions and 3 deletions

144
FIX_LOGO_PDF_PDFMONKEY.md Normal file
View file

@ -0,0 +1,144 @@
# Correction du Bug - Logos Cassés dans les PDFs PDFMonkey
## 🐛 Problème
Lors de la génération de contrats PDF via PDFMonkey, les logos des clients apparaissaient cassés (image non chargée).
## 🔍 Diagnostic
### Flux actuel (bugué)
1. **Upload du logo** (`/app/(app)/staff/clients/[id]/page.tsx`) :
- L'utilisateur upload un logo via le composant `ImageUpload`
- Le fichier est lu et converti en base64
- ❌ **Seule la partie base64 était extraite** (sans le préfixe `data:image/png;base64,`)
- Exemple : `iVBORw0KGgoAAAANS...` au lieu de `data:image/png;base64,iVBORw0KGgoAAAANS...`
2. **Sauvegarde en base** (`/app/api/staff/clients/[id]/route.ts`) :
- Le logo est sauvegardé dans `organization_details.logo`
- Valeur stockée : base64 pur (sans préfixe)
3. **Génération PDF** (`/app/api/contrats/[id]/generate-pdf/route.ts`) :
- Le champ `imageUrl` du payload PDFMonkey reçoit `orgDetails.logo`
- ❌ **PDFMonkey reçoit une chaîne base64 sans préfixe** → image cassée
### Pourquoi ça casse ?
PDFMonkey accepte pour le champ `imageUrl` :
- ✅ Une **URL publique** (ex: `https://example.com/logo.png`)
- ✅ Une **data URI complète** (ex: `data:image/png;base64,iVBORw0KG...`)
- ❌ **PAS** une chaîne base64 brute
## ✅ Solution Implémentée
### 1. Modification de l'Upload (`/app/(app)/staff/clients/[id]/page.tsx`)
**Avant :**
```typescript
const base64 = result.split(',')[1]; // ❌ Extraction du base64 pur
onChange(base64);
```
**Après :**
```typescript
// Conserver la data URI complète
onChange(result); // ✅ Format : data:image/png;base64,iVBORw0KG...
```
### 2. Migration des Logos Existants
Un script SQL a été créé pour mettre à jour les logos existants :
```sql
-- Fichier : MIGRATION_LOGO_DATAURI.sql
UPDATE organization_details
SET logo = 'data:image/png;base64,' || logo
WHERE logo IS NOT NULL
AND logo != ''
AND logo NOT LIKE 'data:%';
```
### 3. Compatibilité Rétroactive
Le composant `LogoLine` gère déjà les deux formats (déjà en place) :
```typescript
<img
src={value.startsWith('data:') ? value : `data:image/png;base64,${value}`}
alt="Logo"
className="max-w-32 max-h-32 object-contain border rounded"
/>
```
Cela garantit que :
- Les nouveaux logos (avec préfixe) s'affichent correctement
- Les anciens logos (sans préfixe, avant migration) s'affichent toujours
- PDFMonkey reçoit toujours le bon format
## 📋 Instructions de Déploiement
### 1. Appliquer le code modifié
```bash
git add app/(app)/staff/clients/[id]/page.tsx
git commit -m "fix: Conserver data URI complète pour logos clients (compatibilité PDFMonkey)"
git push
```
### 2. Exécuter la migration SQL
**Via Supabase Dashboard :**
1. Se connecter à Supabase
2. Aller dans SQL Editor
3. Copier-coller le contenu de `MIGRATION_LOGO_DATAURI.sql`
4. Exécuter la requête
**Via CLI :**
```bash
psql -h db.xxx.supabase.co -U postgres -d postgres -f MIGRATION_LOGO_DATAURI.sql
```
### 3. Vérifier le résultat
1. Aller sur `/staff/clients/[id]` d'un client existant
2. Vérifier que le logo s'affiche correctement
3. Générer un nouveau PDF de contrat
4. Vérifier que le logo apparaît correctement dans le PDF
## 🧪 Tests
### Test 1 : Upload d'un nouveau logo
1. Aller sur `/staff/clients/[id]`
2. Cliquer sur "Modifier"
3. Uploader un nouveau logo
4. Sauvegarder
5. Vérifier que le logo s'affiche
6. Générer un PDF → Le logo doit apparaître
### Test 2 : Logo existant (après migration)
1. Client avec un ancien logo (avant la correction)
2. Après migration SQL, le logo doit s'afficher
3. Générer un PDF → Le logo doit apparaître
### Test 3 : Client sans logo
1. Client sans logo configuré
2. Générer un PDF → Pas d'erreur, juste pas de logo
## 📝 Fichiers Modifiés
- ✅ `app/(app)/staff/clients/[id]/page.tsx` - Correction de l'upload
- ✅ `MIGRATION_LOGO_DATAURI.sql` - Script de migration SQL
- ✅ `FIX_LOGO_PDF_PDFMONKEY.md` - Ce document
## 🔗 Références
- API PDFMonkey : https://pdfmonkey.io/docs
- Data URI scheme : https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
- Template PDFMonkey utilisé : `736E1A5F-BBA1-4D3E-91ED-A6184479B58D`
## ⚠️ Notes Importantes
- Les logos sont stockés directement en base64 dans Supabase (pas sur S3)
- Taille max : 5MB
- Formats acceptés : JPG, PNG, GIF
- Le préfixe `data:image/png;base64,` est ajouté même pour les JPEG (PDFMonkey gère automatiquement)

View file

@ -0,0 +1,29 @@
-- Migration des logos existants pour ajouter le préfixe data:image/png;base64,
-- Contexte : Les logos étaient stockés en base64 pur, mais PDFMonkey a besoin de la data URI complète
-- Afficher d'abord les logos qui vont être modifiés
SELECT
org_id,
CASE
WHEN logo IS NULL THEN 'NULL'
WHEN logo LIKE 'data:%' THEN 'Déjà au bon format'
ELSE 'Sera modifié'
END as status,
LEFT(logo, 50) as logo_preview
FROM organization_details
WHERE logo IS NOT NULL;
-- Mettre à jour les logos qui n'ont pas le préfixe data:image
-- On ajoute le préfixe data:image/png;base64, uniquement si ce n'est pas déjà fait
UPDATE organization_details
SET logo = 'data:image/png;base64,' || logo
WHERE logo IS NOT NULL
AND logo != ''
AND logo NOT LIKE 'data:%';
-- Vérifier le résultat
SELECT
org_id,
LEFT(logo, 50) as logo_preview
FROM organization_details
WHERE logo IS NOT NULL;

View file

@ -198,10 +198,10 @@ function ImageUpload({
reader.onload = (e) => { reader.onload = (e) => {
const result = e.target?.result as string; const result = e.target?.result as string;
if (result) { if (result) {
// Extraire seulement la partie base64 (sans le préfixe data:image/...) // Conserver la data URI complète (avec le préfixe data:image/...;base64,)
const base64 = result.split(',')[1]; // pour compatibilité avec PDFMonkey et l'affichage
setPreview(result); setPreview(result);
onChange(base64); onChange(result);
} }
}; };
reader.readAsDataURL(file); reader.readAsDataURL(file);