feat(Makefile): install frontend dependencies on dev command
feat(Makefile): patch Layout.jsx queryKey for local development feat(frontend-web): mock base44 client for local development with role switching feat(frontend-web): add event assignment modal with conflict detection and bulk assign feat(frontend-web): add client dashboard with key metrics and quick actions feat(frontend-web): add layout component with role-based navigation feat(frontend-web): update various pages to use "@/components" alias feat(frontend-web): update create event page with ai assistant toggle feat(frontend-web): update dashboard page with new components feat(frontend-web): update events page with quick assign popover feat(frontend-web): update invite vendor page with hover card feat(frontend-web): update messages page with conversation list and message thread feat(frontend-web): update operator dashboard page with new components feat(frontend-web): update partner management page with new components feat(frontend-web): update permissions page with new components feat(frontend-web): update procurement dashboard page with new components feat(frontend-web): update smart vendor onboarding page with new components feat(frontend-web): update staff directory page with new components feat(frontend-web): update teams page with new components feat(frontend-web): update user management page with new components feat(frontend-web): update vendor compliance page with new components feat(frontend-web): update main.jsx to include react query provider feat: add vendor marketplace page feat: add global import fix to prepare-export script feat: add patch-layout-query-key script to fix query key feat: update patch-base44-client script to use a more robust method
This commit is contained in:
@@ -8,79 +8,74 @@ const __dirname = path.dirname(__filename);
|
||||
|
||||
const projectRoot = path.join(__dirname, '..', 'frontend-web');
|
||||
|
||||
// --- Fonctions de Patch ---
|
||||
// --- Patching Functions ---
|
||||
|
||||
function applyPatch(filePath, patchInfo) {
|
||||
const fullPath = path.join(projectRoot, filePath);
|
||||
if (!fs.existsSync(fullPath)) {
|
||||
console.warn(`🟡 Fichier non trouvé, patch ignoré : ${filePath}`);
|
||||
console.warn(`🟡 File not found, patch skipped: ${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}').`);
|
||||
if (patchInfo.new_string && content.includes(patchInfo.new_string)) {
|
||||
console.log(`✅ Patch already applied in ${filePath}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (content.includes(patchInfo.old_string)) {
|
||||
if (patchInfo.old_string && 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}').`);
|
||||
console.log(`🟢 Patch applied in ${filePath}.`);
|
||||
} else {
|
||||
console.error(`🔴 Impossible d'appliquer le patch dans ${filePath}. Chaîne non trouvée : '${patchInfo.search_string}'.`);
|
||||
console.error(`🔴 Could not apply patch in ${filePath}. String not found.`);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Définition des Patches ---
|
||||
// --- Global Import Fix ---
|
||||
|
||||
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';
|
||||
function fixAllComponentImports(directory) {
|
||||
const entries = fs.readdirSync(directory, { withFileTypes: true });
|
||||
|
||||
// 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';
|
||||
for (const entry of entries) {
|
||||
const fullPath = path.join(directory, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
// Recursively search in subdirectories
|
||||
fixAllComponentImports(fullPath);
|
||||
} else if (entry.isFile() && (entry.name.endsWith('.jsx') || entry.name.endsWith('.js'))) {
|
||||
let content = fs.readFileSync(fullPath, 'utf8');
|
||||
const originalContent = content;
|
||||
|
||||
// Regex to find all relative imports to the components directory
|
||||
// Handles: from "./components/", from "../components/", from "../../components/", etc.
|
||||
const importRegex = /from\s+(['"])((\.\.\/)+|\.\/)components\//g;
|
||||
|
||||
content = content.replace(importRegex, 'from $1@/components/');
|
||||
|
||||
// --- 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'
|
||||
if (content !== originalContent) {
|
||||
console.log(`✅ Fixing component imports in ${fullPath}`);
|
||||
fs.writeFileSync(fullPath, content, 'utf8');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
|
||||
// --- Exécution ---
|
||||
|
||||
function main() {
|
||||
console.log('--- Applying patches for local environment ---');
|
||||
|
||||
// The specific patches are now less critical as the global fix is more robust,
|
||||
// but we can keep them for specific, non-import related changes.
|
||||
const patches = [
|
||||
{
|
||||
file: 'src/main.jsx',
|
||||
old_string: `ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<App />
|
||||
)`,
|
||||
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';
|
||||
new_string: `import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
@@ -90,17 +85,15 @@ ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<App />
|
||||
</QueryClientProvider>
|
||||
</React.StrictMode>,
|
||||
)
|
||||
`
|
||||
},
|
||||
{
|
||||
file: 'src/pages/Layout.jsx',
|
||||
search_string: `const { data: user } = useQuery`,
|
||||
old_string: ` const { data: user } = useQuery({
|
||||
)`
|
||||
},
|
||||
{
|
||||
file: 'src/pages/Layout.jsx',
|
||||
old_string: `const { data: user } = useQuery({
|
||||
queryKey: ['current-user-layout'],
|
||||
queryFn: () => base44.auth.me(),
|
||||
});`,
|
||||
new_string: ` // const { data: user } = useQuery({
|
||||
new_string: ` // const { data: user } = useQuery({
|
||||
// queryKey: ['current-user-layout'],
|
||||
// queryFn: () => base44.auth.me(),
|
||||
// });
|
||||
@@ -113,90 +106,17 @@ ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
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('--- Global component import fixes ---');
|
||||
fixAllComponentImports(path.join(projectRoot, 'src'));
|
||||
|
||||
console.log('--- Fin de l\'application des patchs ---');
|
||||
console.log('--- End of patching process ---');
|
||||
}
|
||||
|
||||
main();
|
||||
main();
|
||||
|
||||
Reference in New Issue
Block a user