#!/usr/bin/env python3 """Script to update LogoSection.tsx with real upload functionality""" import re file_path = r"C:\Users\jandres\source\repos\SplashPage\src\SplashPage.Web.Ui\src\app\dashboard\settings\captive-portal\_components\portal-config\sections\LogoSection.tsx" with open(file_path, 'r', encoding='utf-8') as f: content = f.read() # 1. Add import if 'usePortalImageUpload' not in content: content = content.replace( "import type { CaptivePortalCfgDto, ImageInfo } from '@/api/types';", "import type { CaptivePortalCfgDto, ImageInfo } from '@/api/types';\nimport { usePortalImageUpload, usePortalImageDelete } from '@/hooks/usePortalImageUpload';" ) # 2. Add hooks after logoImages hooks_code = """ // Upload and delete mutations const uploadMutation = usePortalImageUpload(); const deleteMutation = usePortalImageDelete(); """ if 'uploadMutation' not in content: content = content.replace( " const logoImages = config.logoImages || [];", " const logoImages = config.logoImages || [];" + hooks_code ) # 3. Replace handleFileUpload function old_upload = re.search( r' // Handle file upload\n const handleFileUpload = useCallback\(\n.*? \),\n \[logoImages, onChange\]\n \);', content, re.DOTALL ) new_upload = """ // Handle file upload const handleFileUpload = useCallback( async (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (!file) return; // Validate file type if (!file.type.startsWith('image/')) { toast.error('Por favor seleccione un archivo de imagen válido'); return; } // Validate file size (max 10MB to match backend) if (file.size > 10 * 1024 * 1024) { toast.error('El archivo debe ser menor a 10MB'); return; } setIsUploading(true); try { // Upload to backend using mutation const result = await uploadMutation.mutateAsync({ portalId: config.id!, file, imageType: 'logo', }); // Create ImageInfo object with backend URL const newImage: ImageInfo = { path: result.path, fileName: result.fileName, isSelected: logoImages.length === 0, // Select if first image }; // Add to logo images array onChange({ logoImages: [...logoImages, newImage], }); event.target.value = ''; // Reset input } catch (error) { console.error('Upload error:', error); // Error toast is handled by the hook } finally { setIsUploading(false); } }, [logoImages, onChange, config.id, uploadMutation] );""" if old_upload: content = content.replace(old_upload.group(0), new_upload) # 4. Replace handleRemoveLogo function old_remove = re.search( r' // Handle logo removal\n const handleRemoveLogo = useCallback\(\n.*? \),\n \[logoImages, onChange\]\n \);', content, re.DOTALL ) new_remove = """ // Handle logo removal const handleRemoveLogo = useCallback( async (image: ImageInfo) => { try { // Delete from backend await deleteMutation.mutateAsync({ portalId: config.id!, imagePath: image.path, }); // Remove from local state onChange({ logoImages: logoImages.filter((img) => img.path !== image.path), }); } catch (error) { console.error('Delete error:', error); // Error toast is handled by the hook } }, [logoImages, onChange, config.id, deleteMutation] );""" if old_remove: content = content.replace(old_remove.group(0), new_remove) # 5. Update max file size text content = content.replace('PNG, JPG o SVG. Máximo 5MB.', 'PNG, JPG, GIF o SVG. Máximo 10MB.') with open(file_path, 'w', encoding='utf-8') as f: f.write(content) print("✅ LogoSection.tsx actualizado exitosamente")