diff --git a/micro-frontends/sample/package.json b/micro-frontends/sample/package.json
index 85675b1bfcd..1a03f96ad1e 100644
--- a/micro-frontends/sample/package.json
+++ b/micro-frontends/sample/package.json
@@ -10,10 +10,12 @@
"preview": "vite preview"
},
"dependencies": {
+ "@tanstack/react-query": "5.50.1",
+ "axios": "1.7.2",
"i18next": "23.11.5",
- "axios":"1.7.2",
"i18next-http-backend": "2.5.2",
"idb": "8.0.0",
+ "localforage": "^1.10.0",
"react": "19.0.0-beta-26f2496093-20240514",
"react-dom": "19.0.0-beta-26f2496093-20240514",
"react-hook-form": "7.52.0",
diff --git a/micro-frontends/sample/src/App.jsx b/micro-frontends/sample/src/App.jsx
index a22be439a5e..a8f3255d11e 100644
--- a/micro-frontends/sample/src/App.jsx
+++ b/micro-frontends/sample/src/App.jsx
@@ -15,37 +15,65 @@ import LanguageSwitcher from "./components/LanguageSelector";
import MyComponent from "./components/SampleComponent";
// import TestIdb from "./pages/TestIdb.jsx";
// import { isOnline, onNetworkChange } from './networkStatus';
-
+import { useQuery } from "@tanstack/react-query";
import { Suspense, lazy } from "react";
import { BrowserRouter as Router, Route, Routes, Link } from "react-router-dom";
+import withAuth from "./hoc/withAuth";
const routes = [
{
url: "complex-screen",
+ withAuth: true,
component: lazy(() => import("./pages/test")),
},
{
url: "tab-form",
+ withAuth: true,
component: lazy(() => import("./pages/TabForm")),
},
{
url: "TestIdb",
+ withAuth: true,
component: lazy(() => import("./pages/testIdb")),
},
{
url: "sample",
+ withAuth: true,
component: lazy(() => import("./pages/Sample")),
},
{
url: "stepper-form",
+ withAuth: false,
component: lazy(() => import("./pages/StepperForm")),
},
];
+const fetchTodo = async () => {
+ const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
+ return response.json();
+};
+
+export const TodoComponent = () => {
+ const { data, error, isLoading } = useQuery({
+ queryKey: ["todo"],
+ queryFn: fetchTodo,
+ refetchInterval: false,
+ refetchOnMount: false,
+ refetchOnWindowFocus: false,
+ refetchOnReconnect: false,
+ refetchIntervalInBackground: false,
+ });
+
+ if (isLoading) return
Loading...
;
+ if (error) return Error: {error.message}
;
+
+ return {data.title}
;
+};
function App() {
return (
<>
+
Loading...
@@ -72,7 +100,9 @@ function App() {
Loading...
}>
{routes?.map((route) => {
- const Component = route?.component;
+ const Component = route?.withAuth
+ ? withAuth(route?.component)
+ : route?.component;
return (
} />
);
diff --git a/micro-frontends/sample/src/hoc/withAuth.jsx b/micro-frontends/sample/src/hoc/withAuth.jsx
new file mode 100644
index 00000000000..03fa9e33484
--- /dev/null
+++ b/micro-frontends/sample/src/hoc/withAuth.jsx
@@ -0,0 +1,23 @@
+import React, { useLayoutEffect } from "react";
+import withNavigator from "./withNavigator";
+import { useAuthState } from "../state/useAuthState";
+
+const withAuth = (WrappedComponent) => {
+ const { data } = useAuthState();
+ return (props) => {
+ useLayoutEffect(() => {
+ if (data?.isSignedIn) {
+ console.log("user is signed in");
+ } else {
+ console.log("user is not signedin");
+ }
+ return () => {
+ console.log("Component unmounted");
+ };
+ }, []);
+ const WrappedComp = withNavigator(WrappedComponent);
+ return ;
+ };
+};
+
+export default withAuth;
diff --git a/micro-frontends/sample/src/hoc/withNavigator.jsx b/micro-frontends/sample/src/hoc/withNavigator.jsx
new file mode 100644
index 00000000000..ffa4ef657ea
--- /dev/null
+++ b/micro-frontends/sample/src/hoc/withNavigator.jsx
@@ -0,0 +1,28 @@
+import React, { useLayoutEffect } from "react";
+import { useNavigatorState } from "../state/useNavigatorState";
+
+const withNavigator = (WrappedComponent) => {
+ const { setData, data } = useNavigatorState();
+
+ return (props) => {
+ useLayoutEffect(() => {
+ data?.currentScreen != window.location.pathname &&
+ setData({
+ ...data,
+ currentScreen: window.location.pathname,
+ history: data?.history
+ ? [...data?.history, window.location.pathname]
+ : [window.location.pathname],
+ previousScreen: data?.currentScreen,
+ });
+
+ return () => {
+ console.log("Component unmounted withNavigator");
+ };
+ }, []);
+
+ return ;
+ };
+};
+
+export default withNavigator;
diff --git a/micro-frontends/sample/src/main.jsx b/micro-frontends/sample/src/main.jsx
index 8f7d48b8216..c2a38783139 100644
--- a/micro-frontends/sample/src/main.jsx
+++ b/micro-frontends/sample/src/main.jsx
@@ -1,17 +1,23 @@
-import React from 'react'
-import ReactDOM from 'react-dom/client'
-import App from './App.jsx'
-import './index.css'
-import { I18nextProvider } from 'react-i18next';
-import i18n from './configs/i18.js';
+import React from "react";
+import ReactDOM from "react-dom/client";
+import App from "./App.jsx";
+import "./index.css";
+import { I18nextProvider } from "react-i18next";
+import i18n from "./configs/i18.js";
+import { QueryClientProvider } from "@tanstack/react-query";
+import { hydrateAllQueries, queryClient } from "./state/stateConfigs";
+const initializeApp = async () => {
+ await hydrateAllQueries();
+ ReactDOM.createRoot(document.getElementById("root")).render(
+
+
+
+
+
+
+
+ );
+};
-
-
-ReactDOM.createRoot(document.getElementById('root')).render(
-
-
-
-
- ,
-)
+initializeApp();
diff --git a/micro-frontends/sample/src/pages/TabForm.jsx b/micro-frontends/sample/src/pages/TabForm.jsx
index 5cdfe2c9090..c34074f9778 100644
--- a/micro-frontends/sample/src/pages/TabForm.jsx
+++ b/micro-frontends/sample/src/pages/TabForm.jsx
@@ -1,15 +1,23 @@
-import React, { useState } from 'react';
-import { useForm, Controller, useFieldArray } from 'react-hook-form';
-import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
-import 'react-tabs/style/react-tabs.css';
+import React, { useState } from "react";
+import { useForm, Controller, useFieldArray } from "react-hook-form";
+import { Tab, Tabs, TabList, TabPanel } from "react-tabs";
+import "react-tabs/style/react-tabs.css";
+import { useUserState } from "../state/useUserState";
+import { TodoComponent } from "../App";
-
-const RenderField = ({ control, register, name, property, uiSchema, errors }) => {
- if (property.type === 'object') {
+const RenderField = ({
+ control,
+ register,
+ name,
+ property,
+ uiSchema,
+ errors,
+}) => {
+ if (property.type === "object") {
return (
-
+
{property.title}
- {Object.keys(property.properties).map(subKey => (
+ {Object.keys(property.properties).map((subKey) => (
))}
);
- } else if (property.type === 'array') {
+ } else if (property.type === "array") {
const { fields, append, remove } = useFieldArray({
control,
name: name,
});
return (
-
+
{property.title}
{fields.map((field, index) => (
-
- {Object.keys(property.items.properties).map(subKey => (
+
+ {Object.keys(property.items.properties).map((subKey) => (
errors={errors}
/>
))}
-
+
))}
-
+
);
} else {
return (
-
+
);
}
@@ -76,9 +95,15 @@ const RenderField = ({ control, register, name, property, uiSchema, errors }) =>
const TabForm = ({ schema, uiSchema, tabs, conditionalTabs }) => {
const [currentTab, setCurrentTab] = useState(0);
- const { control, register, handleSubmit, watch, formState: { errors } } = useForm();
+ const {
+ control,
+ register,
+ handleSubmit,
+ watch,
+ formState: { errors },
+ } = useForm();
- const onSubmit = data => console.log(data);
+ const onSubmit = (data) => console.log(data);
const isTabVisible = (tab) => {
if (!conditionalTabs[tab]) return true;
@@ -88,219 +113,254 @@ const TabForm = ({ schema, uiSchema, tabs, conditionalTabs }) => {
};
return (
-