diff --git a/frontend/e2e/_capture-demo-screenshots.spec.ts b/frontend/e2e/_capture-demo-screenshots.spec.ts index af34dd4..df65044 100644 --- a/frontend/e2e/_capture-demo-screenshots.spec.ts +++ b/frontend/e2e/_capture-demo-screenshots.spec.ts @@ -18,7 +18,7 @@ test("capture demo-release evidence screenshots", async ({ page, request }) => { await page.screenshot({ path: `${OUT}/02-demo-entry-mobile.png` }); await page.setViewportSize({ width: 1280, height: 900 }); - await page.getByRole("button", { name: "Verken als Operations Manager" }).click(); + await page.getByRole("button", { name: "Verken als Operationsmanager" }).click(); await expect(page).toHaveURL(/\/dashboard$/); await expect(page.getByText("Probeer een demonstratiescenario")).toBeVisible(); await page.screenshot({ path: `${OUT}/03-dashboard-with-scenarios.png`, fullPage: true }); diff --git a/frontend/e2e/_capture-screenshots.spec.ts b/frontend/e2e/_capture-screenshots.spec.ts index 10ffeb0..d3f0558 100644 --- a/frontend/e2e/_capture-screenshots.spec.ts +++ b/frontend/e2e/_capture-screenshots.spec.ts @@ -14,7 +14,7 @@ test("capture the seven main pages", async ({ page, request }) => { await page.goto("/login"); await page.screenshot({ path: `${OUT}/1-login.png` }); - await page.getByRole("button", { name: "Verken als Operations Manager" }).click(); + await page.getByRole("button", { name: "Verken als Operationsmanager" }).click(); await expect(page.getByRole("heading", { name: "Operational metrics" })).toBeVisible(); await page.screenshot({ path: `${OUT}/2-dashboard.png`, fullPage: true }); diff --git a/frontend/e2e/demo-accessibility.spec.ts b/frontend/e2e/demo-accessibility.spec.ts index ff7bd52..52b689b 100644 --- a/frontend/e2e/demo-accessibility.spec.ts +++ b/frontend/e2e/demo-accessibility.spec.ts @@ -38,7 +38,7 @@ test("demo guide does not cover the return form's action buttons on desktop", as test("demo badge and guide trigger are keyboard reachable and Escape closes them", async ({ page }) => { await page.goto("/login"); - await page.getByRole("button", { name: "Verken als Operations Manager" }).click(); + await page.getByRole("button", { name: "Verken als Operationsmanager" }).click(); await expect(page).toHaveURL(/\/dashboard$/); const guideTrigger = page.getByRole("button", { name: /Demo-gids/ }); @@ -74,7 +74,7 @@ test("key demo pages load without console errors", async ({ page }) => { page.on("pageerror", (err) => errors.push(err.message)); await page.goto("/login"); - await page.getByRole("button", { name: "Verken als Operations Manager" }).click(); + await page.getByRole("button", { name: "Verken als Operationsmanager" }).click(); await expect(page).toHaveURL(/\/dashboard$/); await page.goto("/scenarios"); await expect(page.getByRole("heading", { name: "Probeer een demonstratiescenario" })).toBeVisible(); @@ -96,7 +96,7 @@ test("status-recommendation panel is fully keyboard operable, respects reduced m await page.emulateMedia({ reducedMotion: "reduce" }); await page.goto("/login"); - await page.getByRole("button", { name: "Verken als Operations Manager" }).click(); + await page.getByRole("button", { name: "Verken als Operationsmanager" }).click(); await expect(page).toHaveURL(/\/dashboard$/); await page.goto("/data-quality/DQ-DEMO-STATUS"); diff --git a/frontend/e2e/demo-entry.spec.ts b/frontend/e2e/demo-entry.spec.ts index 4b4c7ae..4a1b51f 100644 --- a/frontend/e2e/demo-entry.spec.ts +++ b/frontend/e2e/demo-entry.spec.ts @@ -7,8 +7,8 @@ test("demo entry screen names the fictional org and never shows a password", asy await expect(page.getByText(/Northstar Mobility/)).toBeVisible(); await expect(page.getByText(/Synthetische demo/)).toBeVisible(); await expect(page.getByRole("button", { name: "Start begeleide demo" })).toBeVisible(); - await expect(page.getByRole("button", { name: "Verken als Operations Manager" })).toBeVisible(); - await expect(page.getByRole("button", { name: "Verken als Rental Employee" })).toBeVisible(); + await expect(page.getByRole("button", { name: "Verken als Operationsmanager" })).toBeVisible(); + await expect(page.getByRole("button", { name: "Verken als Verhuurmedewerker" })).toBeVisible(); await expect(page.locator('input[type="password"]')).toHaveCount(0); }); @@ -26,7 +26,7 @@ test("start guided demo logs in as Operations Manager and opens the guide at ste test("permanent demo badge shows a popover with last reset info and a working About link", async ({ page }) => { await page.goto("/login"); - await page.getByRole("button", { name: "Verken als Operations Manager" }).click(); + await page.getByRole("button", { name: "Verken als Operationsmanager" }).click(); await expect(page).toHaveURL(/\/dashboard$/); const trigger = page.getByRole("button", { name: /Synthetische demo/ }); @@ -45,7 +45,7 @@ test("permanent demo badge shows a popover with last reset info and a working Ab test("badge popover closes on Escape and outside click", async ({ page }) => { await page.goto("/login"); - await page.getByRole("button", { name: "Verken als Operations Manager" }).click(); + await page.getByRole("button", { name: "Verken als Operationsmanager" }).click(); await expect(page).toHaveURL(/\/dashboard$/); const trigger = page.getByRole("button", { name: /Synthetische demo/ }); diff --git a/frontend/e2e/demo-guide.spec.ts b/frontend/e2e/demo-guide.spec.ts index 2c1e8b2..b81656a 100644 --- a/frontend/e2e/demo-guide.spec.ts +++ b/frontend/e2e/demo-guide.spec.ts @@ -12,7 +12,7 @@ test.describe.configure({ mode: "serial" }); test("scenario overview lists all 5 scenarios, ready right after a reset", async ({ page, request }) => { await resetDemoData(request); await page.goto("/login"); - await page.getByRole("button", { name: "Verken als Operations Manager" }).click(); + await page.getByRole("button", { name: "Verken als Operationsmanager" }).click(); await expect(page).toHaveURL(/\/dashboard$/); await page.goto("/scenarios"); @@ -27,12 +27,12 @@ test("scenario overview lists all 5 scenarios, ready right after a reset", async test("starting a scenario navigates to its fixed record", async ({ page }) => { await page.goto("/login"); - await page.getByRole("button", { name: "Verken als Operations Manager" }).click(); + await page.getByRole("button", { name: "Verken als Operationsmanager" }).click(); await expect(page).toHaveURL(/\/dashboard$/); await page.goto("/scenarios"); const duplicateCard = page.locator(".scenario-card", { hasText: "dubbele klant" }); - await duplicateCard.getByRole("link", { name: "Start scenario" }).click(); + await duplicateCard.getByRole("link", { name: "Scenario starten" }).click(); await expect(page).toHaveURL(/\/data-quality\/DQ-DEMO-DUPLICATE$/); }); @@ -92,7 +92,7 @@ test("demo guide progress persists across navigation and the trigger shows it", test("demo guide is not shown to a rental employee", async ({ page }) => { await page.goto("/login"); - await page.getByRole("button", { name: "Verken als Rental Employee" }).click(); + await page.getByRole("button", { name: "Verken als Verhuurmedewerker" }).click(); await expect(page).toHaveURL(/\/dashboard$/); await expect(page.getByRole("button", { name: /Demo-gids/ })).toHaveCount(0); }); diff --git a/frontend/e2e/demo-legibility.spec.ts b/frontend/e2e/demo-legibility.spec.ts index 189c247..2613b7c 100644 --- a/frontend/e2e/demo-legibility.spec.ts +++ b/frontend/e2e/demo-legibility.spec.ts @@ -12,7 +12,7 @@ test.describe.configure({ mode: "serial" }); test("return flow pre-fills the suspicious odometer reading and explains why", async ({ page, request }) => { await resetDemoData(request); await page.goto("/login"); - await page.getByRole("button", { name: "Verken als Operations Manager" }).click(); + await page.getByRole("button", { name: "Verken als Operationsmanager" }).click(); await expect(page).toHaveURL(/\/dashboard$/); await page.goto("/bookings/BK-DEMO-RETURN"); @@ -27,12 +27,12 @@ test("return flow pre-fills the suspicious odometer reading and explains why", a await page.getByRole("button", { name: "Retour bevestigen" }).click(); await expect(page.getByRole("heading", { name: "Retour geregistreerd" })).toBeVisible(); await expect(page.getByRole("link", { name: "Automatiseringsstatus bekijken" })).toBeVisible(); - await expect(page.getByRole("link", { name: "Audit trail bekijken" })).toBeVisible(); + await expect(page.getByRole("link", { name: "Auditgeschiedenis bekijken" })).toBeVisible(); }); test("data quality issue detail explains what's wrong and why it matters", async ({ page }) => { await page.goto("/login"); - await page.getByRole("button", { name: "Verken als Operations Manager" }).click(); + await page.getByRole("button", { name: "Verken als Operationsmanager" }).click(); await expect(page).toHaveURL(/\/dashboard$/); await page.goto("/data-quality/DQ-DEMO-DUPLICATE"); @@ -43,7 +43,7 @@ test("data quality issue detail explains what's wrong and why it matters", async test("data quality list can filter to demo scenarios only", async ({ page }) => { await page.goto("/login"); - await page.getByRole("button", { name: "Verken als Operations Manager" }).click(); + await page.getByRole("button", { name: "Verken als Operationsmanager" }).click(); await expect(page).toHaveURL(/\/dashboard$/); await page.goto("/data-quality"); @@ -61,7 +61,7 @@ test("data quality list can filter to demo scenarios only", async ({ page }) => test("knowledge page suggested question returns a grounded, honestly-labelled answer", async ({ page }) => { await page.goto("/login"); - await page.getByRole("button", { name: "Verken als Operations Manager" }).click(); + await page.getByRole("button", { name: "Verken als Operationsmanager" }).click(); await expect(page).toHaveURL(/\/dashboard$/); await page.goto("/knowledge"); diff --git a/frontend/e2e/demo.spec.ts b/frontend/e2e/demo.spec.ts index 0d3fdf6..de579a1 100644 --- a/frontend/e2e/demo.spec.ts +++ b/frontend/e2e/demo.spec.ts @@ -19,7 +19,7 @@ test("five-minute demo script end to end", async ({ page, request }) => { await test.step("1. login as Operations Manager", async () => { await page.goto("/login"); await expect(page.getByText(/Synthetische demo/)).toBeVisible(); - await page.getByRole("button", { name: "Verken als Operations Manager" }).click(); + await page.getByRole("button", { name: "Verken als Operationsmanager" }).click(); await expect(page).toHaveURL(/\/dashboard$/); }); diff --git a/frontend/e2e/fleet-ops-correction.spec.ts b/frontend/e2e/fleet-ops-correction.spec.ts index 1bd0ba8..cbdb37f 100644 --- a/frontend/e2e/fleet-ops-correction.spec.ts +++ b/frontend/e2e/fleet-ops-correction.spec.ts @@ -19,9 +19,9 @@ async function resetDemoData(request: APIRequestContext) { } const EXPLORE_OPS_MANAGER: Record = { - "nl-BE": "Verken als Operations Manager", + "nl-BE": "Verken als Operationsmanager", "en-GB": "Explore as Operations Manager", - "fr-BE": "Explorer en tant qu'Operations Manager", + "fr-BE": "Explorer en tant que Responsable des opérations", }; const REVIEW_RECOMMENDATION: Record = { @@ -74,6 +74,16 @@ test.describe("branding", () => { } }); +test("the Fleet Ops favicon is linked and resolves (not the browser's blank-tab default)", async ({ page, request }) => { + await resetDemoData(request); + await page.goto("/login"); + const href = await page.locator('link[rel="icon"]').getAttribute("href"); + expect(href).toBe("/favicon.svg"); + const response = await page.request.get(href as string); + expect(response.ok()).toBeTruthy(); + expect(response.headers()["content-type"]).toContain("svg"); +}); + test("language switcher control changes the UI and persists across a reload", async ({ page, request }) => { await resetDemoData(request); // Deliberately not using loginAsOpsManager here: its addInitScript would re-force diff --git a/frontend/src/i18n/locales/fr-BE/audit.json b/frontend/src/i18n/locales/fr-BE/audit.json index e7cda2e..a8a8b61 100644 --- a/frontend/src/i18n/locales/fr-BE/audit.json +++ b/frontend/src/i18n/locales/fr-BE/audit.json @@ -4,8 +4,8 @@ "description": "Suivez les changements d'état importants, les acteurs et les références corrélées.", "actionFilterLabel": "Action", "actionFilterPlaceholder": "p. ex. demo_login", - "managerOnly": "La piste d'audit est visible uniquement pour les Operations Managers.", - "managerOnlyDetail": "L'historique d'audit est visible uniquement pour les Operations Managers.", + "managerOnly": "La piste d'audit est visible uniquement pour les Responsables des opérations.", + "managerOnlyDetail": "L'historique d'audit est visible uniquement pour les Responsables des opérations.", "loading": "Chargement de la piste d'audit…", "unavailable": "La piste d'audit est actuellement indisponible.", "empty": "Aucun événement d'audit trouvé", diff --git a/frontend/src/i18n/locales/fr-BE/auth.json b/frontend/src/i18n/locales/fr-BE/auth.json index ead5bc9..e68b016 100644 --- a/frontend/src/i18n/locales/fr-BE/auth.json +++ b/frontend/src/i18n/locales/fr-BE/auth.json @@ -9,15 +9,15 @@ "accessHeading": "Choisissez comment démarrer", "accessIntro": "Aucun mot de passe requis. Chaque rôle ouvre un environnement synthétique délimité — tous les workflows et contrôles sont réellement implémentés.", "startGuidedDemo": "Démarrer la démo guidée", - "exploreAsOperationsManager": "Explorer en tant qu'Operations Manager", + "exploreAsOperationsManager": "Explorer en tant que Responsable des opérations", "exploreAsOperationsManagerDetail": "Vue d'ensemble complète, résolution qualité et nouvelles tentatives", - "exploreAsRentalEmployee": "Explorer en tant que Rental Employee", + "exploreAsRentalEmployee": "Explorer en tant que Collaborateur de location", "exploreAsRentalEmployeeDetail": "Réservations, retours, flotte et procédures", "safeByDesignTitle": "Conçu pour la sécurité", "safeByDesignDetail": "Chaque action est enregistrée et peut être réinitialisée dans cette démo.", "loginFailed": "La session de démo n'a pas pu démarrer. L'API est peut-être inaccessible.", - "roleOperationsManager": "Operations manager", - "roleRentalEmployee": "Rental employee", + "roleOperationsManager": "Responsable des opérations", + "roleRentalEmployee": "Collaborateur de location", "switchRole": "Changer de rôle", "logout": "Déconnexion" } diff --git a/frontend/src/i18n/locales/fr-BE/demo.json b/frontend/src/i18n/locales/fr-BE/demo.json index fc5f02e..d467c1e 100644 --- a/frontend/src/i18n/locales/fr-BE/demo.json +++ b/frontend/src/i18n/locales/fr-BE/demo.json @@ -32,7 +32,7 @@ "understand-state": { "title": "1. Comprendre l'état opérationnel", "whatYouWillSee": "Le tableau de bord affiche la disponibilité de la flotte, les points d'attention ouverts et les mouvements du jour.", - "whyItMatters": "Un Operations Manager commence chaque journée par cet aperçu pour décider où intervenir.", + "whyItMatters": "Un Responsable des opérations commence chaque journée par cet aperçu pour décider où intervenir.", "startAction": "Ouvrez le tableau de bord et consultez la file d'attention et la chronologie du jour.", "expectedOutcome": "Vous voyez quelles réservations, véhicules ou problèmes de qualité nécessitent de l'attention." }, @@ -102,8 +102,8 @@ "startScenario": "Démarrer le scénario", "roleOr": "{{a}} ou {{b}}", "roles": { - "operations_manager": "Operations Manager", - "rental_employee": "Rental Employee" + "operations_manager": "Responsable des opérations", + "rental_employee": "Collaborateur de location" }, "items": { "return-anomaly": { @@ -155,7 +155,7 @@ "problemTitle": "Le problème fictif", "problemBody": "{{orgName}} loue environ 50 campings-cars et fourgonnettes depuis un site principal. Les réservations, retours, fiches clients et l'entretien vivaient jusqu'ici dans des feuilles de calcul séparées et des échanges verbaux, si bien que les problèmes (clients en double, kilométrages incorrects, véhicules réservés en double) n'apparaissaient que tardivement. {{productName}} montre comment un système unique et connecté signale ces problèmes tôt et permet de les résoudre de façon contrôlée.", "scopeTitle": "Pour qui et avec quelle portée", - "scopeBody": "Cette démo s'adresse à quiconque veut voir comment {{productName}} traite les problèmes opérationnels d'un petit loueur : Operations Managers et Rental Employees, et toute personne évaluant l'approche. La portée est délibérément limitée à une preuve de concept unique et cohérente — pas de comptabilité, pas de paiements, pas de réservations publiques, pas de CRM ou ERP complet.", + "scopeBody": "Cette démo s'adresse à quiconque veut voir comment {{productName}} traite les problèmes opérationnels d'un petit loueur : Responsables des opérations et Collaborateurs de location, et toute personne évaluant l'approche. La portée est délibérément limitée à une preuve de concept unique et cohérente — pas de comptabilité, pas de paiements, pas de réservations publiques, pas de CRM ou ERP complet.", "realTitle": "Ce qui fonctionne réellement", "realBody": "Tout ce qui suit est du code fonctionnel, pas seulement une maquette : accès et sessions basés sur les rôles, gestion des véhicules et réservations, traitement des retours avec validation côté serveur, cinq règles de qualité des données avec chacune sa propre étape de résolution, une piste d'audit complète, une livraison automatisée vers n8n avec nouvelles tentatives limitées, un déploiement basé sur Docker, et une suite de tests automatisés (backend et Playwright de bout en bout).", "syntheticTitle": "Ce qui est synthétique", @@ -170,7 +170,7 @@ "integrationsDescription": "Ce qui est opérationnel, ce qui est en mode démo, et ce qui n'est pas encore connecté.", "resetTitle": "Restaurer l'environnement de démo", "resetBodyManager": "L'environnement peut être réinitialisé à son état de départ à tout moment. Dernière réinitialisation : {{when}}. Utilisez Réinitialiser les données de démo dans la barre latérale pour recommencer.", - "resetBodyEmployee": "L'environnement peut être réinitialisé à son état de départ à tout moment. Dernière réinitialisation : {{when}}. Un Operations Manager peut réinitialiser l'environnement de démo via la barre latérale.", + "resetBodyEmployee": "L'environnement peut être réinitialisé à son état de départ à tout moment. Dernière réinitialisation : {{when}}. Un Responsable des opérations peut réinitialiser l'environnement de démo via la barre latérale.", "limitationsTitle": "Limitations", "limitationsBody": "Ceci est une preuve de concept ciblée, pas un ERP complet. RAGcore et l'ITWorx MCP Hub ne sont pas encore connectés en direct ; l'assistant de connaissances utilise une base de connaissances de démo locale et délimitée au lieu d'un environnement RAGcore en direct.", "unknown": "inconnu" diff --git a/frontend/src/i18n/locales/fr-BE/integrations.json b/frontend/src/i18n/locales/fr-BE/integrations.json index 6ee7997..2c4a29a 100644 --- a/frontend/src/i18n/locales/fr-BE/integrations.json +++ b/frontend/src/i18n/locales/fr-BE/integrations.json @@ -41,7 +41,7 @@ "statusSucceeded": "Réussi", "statusFailed": "Échoué", "unavailable": "Les tâches d'automatisation sont actuellement indisponibles.", - "managerOnly": "L'automatisation est visible uniquement pour les Operations Managers.", + "managerOnly": "L'automatisation est visible uniquement pour les Responsables des opérations.", "loading": "Chargement des tâches d'automatisation…", "empty": "Aucune tâche d'automatisation ne correspond à ce filtre.", "count": "{{count}} événements de workflow", diff --git a/frontend/src/i18n/locales/fr-BE/quality.json b/frontend/src/i18n/locales/fr-BE/quality.json index f0571d6..9693782 100644 --- a/frontend/src/i18n/locales/fr-BE/quality.json +++ b/frontend/src/i18n/locales/fr-BE/quality.json @@ -55,8 +55,8 @@ "title": "Examinez les preuves enregistrées et consignez une résolution auditée.", "notFound": "Ce problème est introuvable.", "loading": "Chargement des preuves du problème…", - "managerOnly": "L'atelier qualité est visible uniquement pour les Operations Managers.", - "managerOnlyDetail": "Les preuves et résolutions de qualité des données sont visibles uniquement pour les Operations Managers.", + "managerOnly": "L'atelier qualité est visible uniquement pour les Responsables des opérations.", + "managerOnlyDetail": "Les preuves et résolutions de qualité des données sont visibles uniquement pour les Responsables des opérations.", "summary": { "rule": "Règle", "entity": "Entité", @@ -212,7 +212,7 @@ "reviewAgain": "Revoir la recommandation", "manualReview": { "heading": "Évaluation manuelle requise", - "body": "Les faits concernant ce véhicule se contredisent. Un Operations Manager doit évaluer la situation en personne plutôt que d'appliquer un changement de statut automatique.", + "body": "Les faits concernant ce véhicule se contredisent. Un Responsable des opérations doit évaluer la situation en personne plutôt que d'appliquer un changement de statut automatique.", "hint": "Utilisez « Reporter » ou « Rejeter » ci-dessous, ou examinez manuellement le véhicule et les réservations concernées." }, "noConflict": { diff --git a/frontend/src/i18n/locales/nl-BE/audit.json b/frontend/src/i18n/locales/nl-BE/audit.json index e6dd60b..dd41e31 100644 --- a/frontend/src/i18n/locales/nl-BE/audit.json +++ b/frontend/src/i18n/locales/nl-BE/audit.json @@ -1,13 +1,13 @@ { "eyebrow": "Bewaken / Onveranderlijke geschiedenis", - "title": "Audit trail", + "title": "Auditgeschiedenis", "description": "Volg belangrijke statuswijzigingen, actoren en gekoppelde gebeurtenissen op.", "actionFilterLabel": "Actie", "actionFilterPlaceholder": "bv. demo-login", - "managerOnly": "De audit trail is enkel zichtbaar voor Operations Managers.", - "managerOnlyDetail": "Auditgeschiedenis is enkel zichtbaar voor Operations Managers.", - "loading": "Audit trail laden…", - "unavailable": "Audit trail is momenteel niet beschikbaar.", + "managerOnly": "De auditgeschiedenis is enkel zichtbaar voor Operationsmanagers.", + "managerOnlyDetail": "Auditgeschiedenis is enkel zichtbaar voor Operationsmanagers.", + "loading": "Auditgeschiedenis laden…", + "unavailable": "Auditgeschiedenis is momenteel niet beschikbaar.", "empty": "Geen auditgebeurtenissen gevonden", "emptyDetail": "Pas het actiefilter aan.", "relatedFilterActive": "Enkel gebeurtenissen gekoppeld aan deze actie ({{count}} gerelateerde gebeurtenissen).", @@ -16,7 +16,7 @@ "storedRendered": "UTC opgeslagen · Brussel weergegeven", "columns": { "when": "Wanneer", - "actor": "Actor", + "actor": "Uitvoerder", "action": "Actie", "entity": "Entiteit", "change": "Wijziging", diff --git a/frontend/src/i18n/locales/nl-BE/auth.json b/frontend/src/i18n/locales/nl-BE/auth.json index e92c159..4e181cf 100644 --- a/frontend/src/i18n/locales/nl-BE/auth.json +++ b/frontend/src/i18n/locales/nl-BE/auth.json @@ -9,15 +9,15 @@ "accessHeading": "Kies hoe je wil starten", "accessIntro": "Geen wachtwoord nodig. Elke rol opent een afgebakende, synthetische omgeving — alle workflows en controles zijn echt geïmplementeerd.", "startGuidedDemo": "Start begeleide demo", - "exploreAsOperationsManager": "Verken als Operations Manager", + "exploreAsOperationsManager": "Verken als Operationsmanager", "exploreAsOperationsManagerDetail": "Volledig overzicht, kwaliteitsoplossing en herpogingen", - "exploreAsRentalEmployee": "Verken als Rental Employee", + "exploreAsRentalEmployee": "Verken als Verhuurmedewerker", "exploreAsRentalEmployeeDetail": "Boekingen, retours, wagenpark en procedures", "safeByDesignTitle": "Veilig ontworpen", "safeByDesignDetail": "Elke actie wordt gelogd en is in deze demo herstelbaar.", "loginFailed": "De demo-sessie kon niet gestart worden. De API is mogelijk niet bereikbaar.", - "roleOperationsManager": "Operations manager", - "roleRentalEmployee": "Rental employee", + "roleOperationsManager": "Operationsmanager", + "roleRentalEmployee": "Verhuurmedewerker", "switchRole": "Wissel van rol", "logout": "Uitloggen" } diff --git a/frontend/src/i18n/locales/nl-BE/demo.json b/frontend/src/i18n/locales/nl-BE/demo.json index dadb4e2..6fc3db8 100644 --- a/frontend/src/i18n/locales/nl-BE/demo.json +++ b/frontend/src/i18n/locales/nl-BE/demo.json @@ -32,7 +32,7 @@ "understand-state": { "title": "1. Begrijp de operationele status", "whatYouWillSee": "Het dashboard toont de wagenparkstatus, openstaande aandachtspunten en de bewegingen van vandaag.", - "whyItMatters": "Een Operations Manager start elke dag met dit overzicht om te bepalen waar ingrijpen nodig is.", + "whyItMatters": "Een Operationsmanager start elke dag met dit overzicht om te bepalen waar ingrijpen nodig is.", "startAction": "Open het dashboard en bekijk de aandachtslijst en de tijdlijn van vandaag.", "expectedOutcome": "Je ziet welke boekingen, voertuigen of datakwaliteitsproblemen aandacht vragen." }, @@ -72,10 +72,10 @@ "expectedOutcome": "Je ziet het antwoord, de gebruikte procedure en de brontekst — of een eerlijk 'onvoldoende informatie' als dat niet aanwezig is." }, "check-automation-audit": { - "title": "7. Controleer automatisering en audit trail", + "title": "7. Controleer automatisering en auditgeschiedenis", "whatYouWillSee": "De status van de n8n-aflevering voor je retour, en de bijhorende audit-gebeurtenissen.", "whyItMatters": "Elke belangrijke actie moet naspeurbaar zijn: wie deed wat, wanneer, en wat was het gevolg.", - "startAction": "Open Integraties om de afleverstatus te zien, en Audit trail voor het volledige spoor.", + "startAction": "Open Integraties om de afleverstatus te zien, en Auditgeschiedenis voor het volledige spoor.", "expectedOutcome": "Je ziet een geslaagde (of herstelbare) aflevering en een leesbaar audit-overzicht van je acties." }, "review-real-vs-simulated": { @@ -99,22 +99,22 @@ "role": "Rol", "demonstrates": "Toont aan:", "requiresRole": "Vereist rol: {{roles}}.", - "startScenario": "Start scenario", + "startScenario": "Scenario starten", "roleOr": "{{a}} of {{b}}", "roles": { - "operations_manager": "Operations Manager", - "rental_employee": "Rental Employee" + "operations_manager": "Operationsmanager", + "rental_employee": "Verhuurmedewerker" }, "items": { "return-anomaly": { "title": "Retour met afwijkende kilometerstand", "problem": "Een voertuig komt terug met een kilometerstand die lager ligt dan de laatst geregistreerde stand — een teken van een foutieve invoer of een verwisseld voertuig.", - "demonstrates": "Retourverwerking, automatische detectie van datakwaliteitsproblemen en de audit trail die daaruit ontstaat." + "demonstrates": "Retourverwerking, automatische detectie van datakwaliteitsproblemen en de auditgeschiedenis die daaruit ontstaat." }, "duplicate-customer": { "title": "Mogelijke dubbele klant samenvoegen", "problem": "Twee klantprofielen delen hetzelfde e-mailadres en telefoonnummer — waarschijnlijk dezelfde persoon, twee keer geregistreerd.", - "demonstrates": "Samenvoegen van klanten met behoud van boekingsgeschiedenis en audit trail." + "demonstrates": "Samenvoegen van klanten met behoud van boekingsgeschiedenis en auditgeschiedenis." }, "booking-overlap": { "title": "Overlappende boekingen herstellen", @@ -155,9 +155,9 @@ "problemTitle": "Het fictieve probleem", "problemBody": "{{orgName}} verhuurt zo'n 50 campers en bestelwagens vanuit één hoofdlocatie. Boekingen, retours, klantgegevens en onderhoud kwamen tot nu toe uit losse spreadsheets en mondelinge afspraken, waardoor fouten (dubbele klanten, foutieve kilometerstanden, dubbel geboekte voertuigen) laat aan het licht kwamen. {{productName}} toont hoe één samenhangend systeem die problemen vroeg signaleert en gecontroleerd laat oplossen.", "scopeTitle": "Voor wie en met welke scope", - "scopeBody": "Deze demo is bedoeld voor wie wil zien hoe {{productName}} operationele problemen bij een kleine verhuurder aanpakt: Operations Managers en Rental Employees, en iedereen die de aanpak evalueert. De scope is bewust afgebakend tot één samenhangende proof of concept — geen boekhouding, geen betalingen, geen publieke reservaties, geen volledig CRM of ERP.", + "scopeBody": "Deze demo is bedoeld voor wie wil zien hoe {{productName}} operationele problemen bij een kleine verhuurder aanpakt: Operationsmanagers en Verhuurmedewerkers, en iedereen die de aanpak evalueert. De scope is bewust afgebakend tot één samenhangende proof of concept — geen boekhouding, geen betalingen, geen publieke reservaties, geen volledig CRM of ERP.", "realTitle": "Wat écht werkt", - "realBody": "Alles hieronder is functionele code, niet alleen een mockup: rol-gebaseerde toegang en sessies, voertuig- en boekingsbeheer, retourverwerking met serverzijdige validatie, vijf datakwaliteitsregels met elk een eigen oplossingsstap, een volledige audit trail, geautomatiseerde aflevering naar n8n met begrensde herpogingen, Docker-gebaseerde deployment en een geautomatiseerde testsuite (backend en Playwright end-to-end).", + "realBody": "Alles hieronder is functionele code, niet alleen een mockup: rol-gebaseerde toegang en sessies, voertuig- en boekingsbeheer, retourverwerking met serverzijdige validatie, vijf datakwaliteitsregels met elk een eigen oplossingsstap, een volledige auditgeschiedenis, geautomatiseerde aflevering naar n8n met begrensde herpogingen, Docker-gebaseerde deployment en een geautomatiseerde testsuite (backend en Playwright end-to-end).", "syntheticTitle": "Wat synthetisch is", "syntheticBody": "De organisatie, alle klanten, voertuigen, boekingen, onderhoudsgeschiedenis, procedures in de kennisbank en de vooraf ingerichte scenario's zijn volledig verzonnen. Geen enkel gegeven verwijst naar een bestaand persoon, voertuig of bedrijf; e-mailadressen gebruiken uitsluitend het testdomein {{testDomain}}.", "architectureTitle": "Architectuur in het kort", @@ -170,7 +170,7 @@ "integrationsDescription": "Wat operationeel is, wat demomodus is, en wat nog niet gekoppeld is.", "resetTitle": "Demo-omgeving herstellen", "resetBodyManager": "De omgeving is op elk moment terug te zetten naar de startsituatie. Laatste reset: {{when}}. Gebruik Demogegevens herstellen in de zijbalk om opnieuw te beginnen.", - "resetBodyEmployee": "De omgeving is op elk moment terug te zetten naar de startsituatie. Laatste reset: {{when}}. Een Operations Manager kan de demo-omgeving herstellen via de zijbalk.", + "resetBodyEmployee": "De omgeving is op elk moment terug te zetten naar de startsituatie. Laatste reset: {{when}}. Een Operationsmanager kan de demo-omgeving herstellen via de zijbalk.", "limitationsTitle": "Beperkingen", "limitationsBody": "Dit is een gerichte proof of concept, geen volledig ERP. RAGcore en de ITWorx MCP Hub zijn nog niet live gekoppeld; de kennisassistent gebruikt een lokale, afgebakende demokennisbank in plaats van een live RAGcore-omgeving.", "unknown": "onbekend" diff --git a/frontend/src/i18n/locales/nl-BE/integrations.json b/frontend/src/i18n/locales/nl-BE/integrations.json index f08c916..15517b9 100644 --- a/frontend/src/i18n/locales/nl-BE/integrations.json +++ b/frontend/src/i18n/locales/nl-BE/integrations.json @@ -31,7 +31,7 @@ "description": "Vastgelegde automatiseringspogingen met de recentste foutevidentie.", "filterLabel": "Weergave", "filterNeedsAttention": "Vraagt aandacht", - "filterRecent": "Recent", + "filterRecent": "Recentste", "filterSucceeded": "Geslaagd", "filterAll": "Alle", "statusFilterLabel": "Status", @@ -41,7 +41,7 @@ "statusSucceeded": "Geslaagd", "statusFailed": "Mislukt", "unavailable": "Automatiseringsopdrachten zijn momenteel niet beschikbaar.", - "managerOnly": "Automatisering is enkel zichtbaar voor Operations Managers.", + "managerOnly": "Automatisering is enkel zichtbaar voor Operationsmanagers.", "loading": "Automatiseringsopdrachten laden…", "empty": "Geen automatiseringsopdrachten voor dit filter.", "count": "{{count}} workflowgebeurtenissen", diff --git a/frontend/src/i18n/locales/nl-BE/navigation.json b/frontend/src/i18n/locales/nl-BE/navigation.json index 0f1f1cc..2c29003 100644 --- a/frontend/src/i18n/locales/nl-BE/navigation.json +++ b/frontend/src/i18n/locales/nl-BE/navigation.json @@ -11,7 +11,7 @@ "quality": "Datakwaliteit", "knowledge": "Kennis", "integrations": "Integraties", - "audit": "Audit trail" + "audit": "Auditgeschiedenis" }, "primaryNavLabel": "Hoofdnavigatie", "mobileNavLabel": "Mobiele navigatie", diff --git a/frontend/src/i18n/locales/nl-BE/quality.json b/frontend/src/i18n/locales/nl-BE/quality.json index 07c9a2c..c5ec0db 100644 --- a/frontend/src/i18n/locales/nl-BE/quality.json +++ b/frontend/src/i18n/locales/nl-BE/quality.json @@ -14,7 +14,7 @@ "scanFailed": "Kwaliteitscontrole kon niet uitgevoerd worden.", "statusLabel": "Status", "statusAll": "Alle statussen", - "statusOpen": "Open", + "statusOpen": "Openstaand", "statusDeferred": "Uitgesteld", "statusResolved": "Opgelost", "statusRejected": "Verworpen", @@ -55,8 +55,8 @@ "title": "Bekijk vastgelegde evidentie en registreer een geauditeerde oplossing.", "notFound": "Dit probleem kon niet gevonden worden.", "loading": "Probleemevidentie laden…", - "managerOnly": "De kwaliteitswerkbank is enkel zichtbaar voor Operations Managers.", - "managerOnlyDetail": "Datakwaliteitsevidentie en -oplossingen zijn enkel zichtbaar voor Operations Managers.", + "managerOnly": "De kwaliteitswerkbank is enkel zichtbaar voor Operationsmanagers.", + "managerOnlyDetail": "Datakwaliteitsevidentie en -oplossingen zijn enkel zichtbaar voor Operationsmanagers.", "summary": { "rule": "Regel", "entity": "Entiteit", @@ -64,8 +64,8 @@ }, "resolved": { "title": "Probleem {{ref}} opgelost", - "body": "De wijziging is doorgevoerd en vastgelegd in de audit trail.", - "viewAudit": "Audit trail bekijken", + "body": "De wijziging is doorgevoerd en vastgelegd in de auditgeschiedenis.", + "viewAudit": "Auditgeschiedenis bekijken", "viewVehicle": "Voertuig bekijken", "continueDemo": "Ga verder met de demo" }, @@ -201,7 +201,7 @@ "consequence": { "statusWillChange": "De voertuigstatus wordt gewijzigd naar {{status}}.", "issueWillBeRechecked": "Dit kwaliteitsprobleem wordt opnieuw gecontroleerd.", - "changeWillBeAudited": "De wijziging wordt vastgelegd in de audit trail.", + "changeWillBeAudited": "De wijziging wordt vastgelegd in de auditgeschiedenis.", "bookingsNotDeleted": "De boekingen zelf worden niet verwijderd." }, "changeStatusTo": "Status wijzigen naar {{status}}", @@ -212,7 +212,7 @@ "reviewAgain": "Aanbeveling opnieuw bekijken", "manualReview": { "heading": "Handmatige beoordeling vereist", - "body": "De feiten voor dit voertuig spreken elkaar tegen. Een Operations Manager moet dit persoonlijk beoordelen in plaats van een automatische statuswijziging toe te passen.", + "body": "De feiten voor dit voertuig spreken elkaar tegen. Een Operationsmanager moet dit persoonlijk beoordelen in plaats van een automatische statuswijziging toe te passen.", "hint": "Gebruik 'Uitstellen' of 'Verwerpen' hieronder, of onderzoek het voertuig en de betrokken boekingen manueel." }, "noConflict": { diff --git a/frontend/src/i18n/locales/nl-BE/returns.json b/frontend/src/i18n/locales/nl-BE/returns.json index 416db01..cc688e9 100644 --- a/frontend/src/i18n/locales/nl-BE/returns.json +++ b/frontend/src/i18n/locales/nl-BE/returns.json @@ -69,7 +69,7 @@ "odometerRegressionNotice": "De ingevoerde kilometerstand lag onder de laatst bevestigde stand van het voertuig. Ze werd zo geregistreerd; de laatst bevestigde kilometerstand is niet gewijzigd en er is een datakwaliteitsprobleem geopend ter controle.", "viewVehicle": "Voertuig {{ref}} bekijken", "viewAutomation": "Automatiseringsstatus bekijken", - "viewAudit": "Audit trail bekijken", + "viewAudit": "Auditgeschiedenis bekijken", "continueDemo": "Ga verder met de demo" }, "scenario": {