diff --git a/public/index.html b/public/index.html
index 5c0049e..8296134 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1,4 +1,4 @@
-
+
@@ -28,8 +28,12 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
-
+
e-suite
+
+
+
+
diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index 580898b..91806ff 100644
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -134,6 +134,7 @@
"PressAgainToUnblock": "Press again to unblock",
"PrintSpecification": "Print Specification",
"Profile": "Profile",
+ "ProfileSaved": "Profile updated.",
"ResendConfirm": "Resend Confirm",
"Required": "Required",
"ResetPassword": "Reset Password",
diff --git a/public/locales/en/htmlIsland.json b/public/locales/en/htmlIsland.json
new file mode 100644
index 0000000..9164421
--- /dev/null
+++ b/public/locales/en/htmlIsland.json
@@ -0,0 +1,8 @@
+{
+ "island": {
+ "loadError": "Failed to load this section.",
+ "networkError": "Network error while saving.",
+ "serverError": "Server error while saving.",
+ "saveSuccess": "Saved successfully."
+ }
+}
diff --git a/public/locales/fr/common.json b/public/locales/fr/common.json
index 4b57008..92ef76b 100644
--- a/public/locales/fr/common.json
+++ b/public/locales/fr/common.json
@@ -134,6 +134,7 @@
"PressAgainToUnblock": "Appuyez de nouveau pour débloquer",
"PrintSpecification": "Imprimer la spécification",
"Profile": "Profil",
+ "ProfileSaved": "Profil mis à jour.",
"ResendConfirm": "Renvoyer la confirmation",
"Required": "Requis",
"ResetPassword": "Réinitialiser le mot de passe",
diff --git a/public/locales/fr/htmlIsland.json b/public/locales/fr/htmlIsland.json
new file mode 100644
index 0000000..1a7258f
--- /dev/null
+++ b/public/locales/fr/htmlIsland.json
@@ -0,0 +1,8 @@
+{
+ "island": {
+ "loadError": "Échec du chargement de cette section.",
+ "networkError": "Erreur réseau lors de l’enregistrement.",
+ "serverError": "Erreur du serveur lors de l’enregistrement.",
+ "saveSuccess": "Enregistré avec succès."
+ }
+}
diff --git a/src/App.tsx b/src/App.tsx
index 868dad9..e71d997 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -9,7 +9,6 @@ import ForgotPassword from "./modules/frame/components/ForgotPassword";
import NotFound from "./modules/frame/components/NotFound";
import Logout from "./modules/frame/components/Logout";
import LoginForm from "./modules/frame/components/LoginForm";
-import Redirect from "./components/common/Redirect";
import Mainframe from "./modules/frame/components/Mainframe";
import EmailUserAction from "./modules/frame/components/EmailUserAction";
import { HashNavigationProvider } from "./utils/HashNavigationContext";
@@ -48,9 +47,7 @@ import { Namespaces } from "./i18n/i18n";
function GetSecureRoutes() {
const { t } = useTranslation();
- const profileRoute = window.__RUNTIME_CONFIG__.EXTERNAL_LOGIN ? (
- } />
- ) : (
+ const profileRoute = (
} />
- ) : (
-
-
-
- }
- />
- );
-
return (
@@ -466,7 +450,14 @@ function App() {
} />
- {loginRoute}
+
+
+
+ }
+ />
= ({
+ url,
+ islandId,
+ successMessage,
+}) => {
+ const [html, setHtml] = useState("");
+ const [error, setError] = useState(null);
+ const containerRef = useRef(null);
+ const { t: tIsland } = useTranslation(Namespaces.HtmlIsland);
+
+ //
+ // Load the island HTML
+ //
+ const loadIsland = useCallback(() => {
+ setError(null);
+
+ fetch(url, { credentials: "include" })
+ .then((r) => {
+ if (!r.ok) throw new Error(`Failed to load island: ${r.status}`);
+ return r.text();
+ })
+ .then((text) => setHtml(text))
+ .catch(() => {
+ setError(tIsland("island.loadError"));
+ toast.error(tIsland("island.loadError"));
+ });
+ }, [url, tIsland]);
+
+ //
+ // Initial load + reload when URL changes
+ //
+ useEffect(() => {
+ loadIsland();
+ }, [loadIsland]);
+
+ //
+ // After HTML is injected, run scripts + bind form handling
+ //
+ useEffect(() => {
+ if (!html || !containerRef.current) return;
+
+ const container = containerRef.current;
+
+ //
+ // 1. Extract and execute