import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; // Replicate __dirname functionality in ES modules const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const projectRoot = path.join(__dirname, '..', 'frontend-web'); // --- Fonctions de Patch --- function applyPatch(filePath, patchInfo) { const fullPath = path.join(projectRoot, filePath); if (!fs.existsSync(fullPath)) { console.warn(`🟡 Fichier non trouvé, patch ignoré : ${filePath}`); return; } let content = fs.readFileSync(fullPath, 'utf8'); if (content.includes(patchInfo.new_string)) { console.log(`✅ Patch déjà appliqué dans ${filePath} (recherche de '${patchInfo.search_string}').`); return; } if (content.includes(patchInfo.old_string)) { content = content.replace(patchInfo.old_string, patchInfo.new_string); fs.writeFileSync(fullPath, content, 'utf8'); console.log(`🟢 Patch appliqué dans ${filePath} (remplacement de '${patchInfo.search_string}').`); } else { console.error(`🔴 Impossible d'appliquer le patch dans ${filePath}. Chaîne non trouvée : '${patchInfo.search_string}'.`); } } // --- Définition des Patches --- const patches = [ { file: 'src/api/base44Client.js', search_string: 'createClient', old_string: `import { createClient } from '@base44/sdk'; // import { getAccessToken } from '@base44/sdk/utils/auth-utils'; // Create a client with authentication required export const base44 = createClient({ appId: "68fc6cf01386035c266e7a5d", requiresAuth: true // Ensure authentication is required for all operations });`, new_string: `// import { createClient } from '@base44/sdk'; // --- MIGRATION MOCK --- // This mock completely disables the Base44 SDK to allow for local development. export const base44 = { auth: { me: () => Promise.resolve(null), logout: () => {}, }, entities: { ActivityLog: { filter: () => Promise.resolve([]), }, }, }; ` }, { file: 'src/main.jsx', search_string: `ReactDOM.createRoot(document.getElementById('root')).render(`, old_string: `import React from 'react' import ReactDOM from 'react-dom/client' import App from '@/App.jsx' import '@/index.css' ReactDOM.createRoot(document.getElementById('root')).render( )`, new_string: `import React from 'react' import ReactDOM from 'react-dom/client' import App from '@/App.jsx' import '@/index.css' import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; const queryClient = new QueryClient(); ReactDOM.createRoot(document.getElementById('root')).render( , ) ` }, { file: 'src/pages/Layout.jsx', search_string: `const { data: user } = useQuery`, old_string: ` const { data: user } = useQuery({ queryKey: ['current-user-layout'], queryFn: () => base44.auth.me(), });`, new_string: ` // const { data: user } = useQuery({ // queryKey: ['current-user-layout'], // queryFn: () => base44.auth.me(), // }); // Mock user data to prevent redirection and allow local development const user = { full_name: "Dev User", email: "dev@example.com", user_role: "admin", // You can change this to 'procurement', 'operator', 'client', etc. to test different navigation menus profile_picture: "https://i.pravatar.cc/150?u=a042581f4e29026024d", }; ` }, { file: 'src/pages/Layout.jsx', search_string: `const { data: unreadCount = 0 } = useQuery`, old_string: ` const { data: unreadCount = 0 } = useQuery({ queryKey: ['unread-notifications', user?.id], queryFn: async () => { if (!user?.id) return 0; const notifications = await base44.entities.ActivityLog.filter({ user_id: user?.id, is_read: false }); return notifications.length; }, enabled: !!user?.id, initialData: 0, refetchInterval: 10000, });`, new_string: ` // Get unread notification count // const { data: unreadCount = 0 } = useQuery({ const unreadCount = 0; // Mocked value` }, { file: 'src/pages/Layout.jsx', search_string: 'import { Badge } from \"./components/ui/badge\"', old_string: 'import { Badge } from \"./components/ui/badge\"', new_string: 'import { Badge } from \"@/components/ui/badge\"', }, { file: 'src/pages/Layout.jsx', search_string: 'import ChatBubble from \"./components/chat/ChatBubble\"', old_string: 'import ChatBubble from \"./components/chat/ChatBubble\"', new_string: 'import ChatBubble from \"@/components/chat/ChatBubble\"', } ]; // --- Global Import Fix --- function fixComponentImports(directory) { const entries = fs.readdirSync(directory, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(directory, entry.name); if (entry.isDirectory()) { fixComponentImports(fullPath); } else if (entry.isFile() && entry.name.endsWith('.jsx')) { let content = fs.readFileSync(fullPath, 'utf8'); const originalContent = content; // Regex to find all imports from "./components/" (with single or double quotes) const importRegex = /from\s+(['"])\.\/components\//g; content = content.replace(importRegex, 'from $1@/components/'); // This specifically handles the badge import which might be different content = content.replace('from "./components/ui/badge"', 'from "@/components/ui/badge"'); content = content.replace('from "./components/chat/ChatBubble"', 'from "@/components/chat/ChatBubble"'); content = content.replace('from "./components/dev/RoleSwitcher"', 'from "@/components/dev/RoleSwitcher"'); content = content.replace('from "./components/notifications/NotificationPanel"', 'from "@/components/notifications/NotificationPanel"'); content = content.replace('from "./components/ui/toaster"', 'from "@/components/ui/toaster"'); if (content !== originalContent) { console.log(` Glogal import fix appliqué dans ${fullPath}`); fs.writeFileSync(fullPath, content, 'utf8'); } } } } // --- Exécution --- function main() { console.log('--- Application des patchs pour l\'environnement local ---'); patches.forEach(patchInfo => { applyPatch(patchInfo.file, patchInfo); }); console.log('--- Correction globale des imports de composants ---'); fixComponentImports(path.join(projectRoot, 'src')); console.log('--- Fin de l\'application des patchs ---'); } main();