diff --git a/.env b/.env
new file mode 100644
index 0000000..42723dc
--- /dev/null
+++ b/.env
@@ -0,0 +1 @@
+NEXT_PUBLIC_BASE_URL=https://api.d.aiengines.ir/rasad/v1
diff --git a/.gitignore b/.gitignore
index 5ef6a52..23bad85 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,7 +31,7 @@ yarn-error.log*
.pnpm-debug.log*
# env files (can opt-in for committing if needed)
-.env*
+.env*.local
# vercel
.vercel
diff --git a/components/base/global.js b/components/base/global.js
new file mode 100644
index 0000000..417198b
--- /dev/null
+++ b/components/base/global.js
@@ -0,0 +1,15 @@
+import { Global } from "@emotion/react";
+
+export const Fonts = () => (
+
+);
diff --git a/contexts/KeycloakContext.js b/contexts/KeycloakContext.js
new file mode 100644
index 0000000..f1c9842
--- /dev/null
+++ b/contexts/KeycloakContext.js
@@ -0,0 +1,36 @@
+import keycloak from "@/lib/keycloak";
+import { createContext, useContext, useEffect, useState } from "react";
+
+const KeycloakContext = createContext();
+
+let keycloakInitialized = false;
+
+export const KeycloakProvider = ({ children }) => {
+ const [initialized, setInitialized] = useState(false);
+ const [authenticated, setAuthenticated] = useState(false);
+
+ useEffect(() => {
+ if (!keycloakInitialized) {
+ keycloakInitialized = true;
+ keycloak
+ .init({
+ onLoad: "login-required",
+ checkLoginIframe: false,
+ flow: "implicit",
+ })
+ .then((auth) => {
+ setAuthenticated(auth);
+ setInitialized(true);
+ })
+ .catch((err) => {});
+ }
+ }, []);
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const useKeycloak = () => useContext(KeycloakContext);
diff --git a/lib/api.js b/lib/api.js
new file mode 100644
index 0000000..6e4f5b9
--- /dev/null
+++ b/lib/api.js
@@ -0,0 +1,54 @@
+import axios from "axios";
+import keycloak from "./keycloak";
+
+export const baseUrl = process.env.NEXT_PUBLIC_BASE_URL;
+
+const axiosInstance = axios.create({
+ baseURL: baseUrl,
+});
+
+axiosInstance.interceptors.request.use(
+ async (config) => {
+ // if (keycloak?.authenticated) {
+ // config.headers.Authorization = `Bearer ${keycloak.token}`;
+ // await keycloak.updateToken(30);
+ // }
+ return config;
+ },
+ (error) => Promise.reject(error),
+);
+
+axiosInstance.interceptors.response.use(
+ (response) => response,
+ async (error) => {
+ const originalRequest = error.config;
+
+ // if (error?.response?.status === 401 && !originalRequest._retry) {
+ // originalRequest._retry = true;
+ // keycloak.login();
+ // try {
+ // await keycloak.updateToken(30);
+ // const newToken = keycloak.token;
+
+ // if (newToken) {
+ // originalRequest.headers["Authorization"] = `Bearer ${newToken}`;
+ // return axiosInstance(originalRequest);
+ // }
+ // } catch (refreshError) {
+ // localStorage.removeItem("access_account");
+ // keycloak.logout({ redirectUri: window.location.origin });
+ // }
+ // }
+
+ return Promise.reject(error);
+ },
+);
+
+// ✅ Fetcher for GET (used in SWR)
+export const fetcher = async (url) => {
+ const fullUrl = url.startsWith("http") ? url : `${baseUrl}${url}`;
+ const resp = await axiosInstance.get(fullUrl);
+ return resp.data;
+};
+
+export default axiosInstance;
diff --git a/lib/keycloak.js b/lib/keycloak.js
new file mode 100644
index 0000000..a7fa485
--- /dev/null
+++ b/lib/keycloak.js
@@ -0,0 +1,16 @@
+import Keycloak from "keycloak-js";
+
+const keycloak = new Keycloak({
+ url: "https://auth.ibagher.ir",
+ realm: "bi",
+ clientId: "rasad",
+});
+
+export const initKeycloak = () =>
+ keycloak.init({
+ onLoad: "login-required",
+ checkLoginIframe: false, // optional
+ flow: "implicit", // You can change this to 'standard' if you use authorization code flow
+ });
+
+export default keycloak;
diff --git a/package.json b/package.json
index cf23b0b..064b3c9 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,9 @@
"@chakra-ui/react": "2",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
+ "axios": "^1.13.5",
"framer-motion": "^12.34.3",
+ "keycloak-js": "^26.2.3",
"next": "16.1.6",
"next-query-params": "^5.1.0",
"react": "19.2.3",
diff --git a/pages/_app.js b/pages/_app.js
index 1b364eb..cd6662d 100644
--- a/pages/_app.js
+++ b/pages/_app.js
@@ -3,17 +3,30 @@ import { ChakraProvider } from "@chakra-ui/react";
import { QueryParamProvider } from "use-query-params";
import { NextAdapter } from "next-query-params";
import { theme } from "@/components/theme";
+import { useKeycloak } from "@/contexts/KeycloakContext";
+import { SWRConfig } from "swr";
+import { fetcher } from "@/lib/api";
+import { Fonts } from "@/components/base/global";
+
+const Adapter = (props) => ;
export default function App({ Component, pageProps }) {
- const Adapter = (props) => ;
+ // const { initialized, authenticated } = useKeycloak();
+
+ // if (!initialized) return ;
+ // if (!authenticated) return
Redirecting to login...
;
return (
-
-
+
+
+
-
+
);
}
diff --git a/pages/_document.js b/pages/_document.js
index b2fff8b..81db55d 100644
--- a/pages/_document.js
+++ b/pages/_document.js
@@ -3,7 +3,10 @@ import { Html, Head, Main, NextScript } from "next/document";
export default function Document() {
return (
-
diff --git a/pages/index.js b/pages/index.js
index 59d510c..cdebb2f 100644
--- a/pages/index.js
+++ b/pages/index.js
@@ -12,18 +12,10 @@ import {
TabPanel,
TabPanels,
Icon,
- Divider,
HStack,
Image,
- Stack,
} from "@chakra-ui/react";
-import {
- FiFileText,
- FiImage,
- FiVideo,
- FiLayers,
- FiSettings,
-} from "react-icons/fi";
+import { FiImage, FiLayers } from "react-icons/fi";
import { CiVideoOn } from "react-icons/ci";
import {
IoDocumentTextOutline,
@@ -31,7 +23,6 @@ import {
IoVideocamOutline,
} from "react-icons/io5";
import { IoIosGitMerge } from "react-icons/io";
-
import {
NumberParam,
StringParam,
@@ -39,7 +30,6 @@ import {
withDefault,
} from "use-query-params";
import { BsChatText } from "react-icons/bs";
-// import { StringParam, useQueryParams, withDefault } from "use-query-params";
export default function Home() {
const [filters, setFilters] = useQueryParams({
@@ -49,174 +39,153 @@ export default function Home() {
});
return (
-
- {/* Main Content */}
-
-
- {/* Brand / Title */}
-
-
- سرویس ها
-
-
- داشبورد تولید محتوا
-
-
+
+ {/* Header */}
+
-
-
- {/* Menu */}
- setFilters({ model_name: e })}
- index={filters?.model_name}
- >
-
- خانم ستاری
- رکن آبادی
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {/* Footer */}
-
-
-
-
+ {/* Page Layout */}
+
+ {/* Sidebar */}
-
-
-
- موسسه تولید سیستم های خبره و هوشمند اسلامی باقرالعلوم(ع)
-
+
+ {/* Menu */}
+ setFilters({ model_name: e })}
+ index={filters?.model_name}
+ >
+
+ خانم ستاری
+ رکن آبادی
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Footer */}
-
+
+ {/* Content */}
+
-
-
- {/* Right Sidebar */}
+
);
}
-function SidebarItem({
- icon,
- label,
- active = false,
- filters,
- setFilters,
- name,
-}) {
+function AppHeader() {
+ return (
+
+
+
+
+
+ سامانه تولید محتوای هوشمند
+
+
+ سامانه جامع تولید محتوا با استفاده از مدلهای زبانی و مولد تصویر و
+ ویدئو
+
+
+
+
+
+
+ موسسه تولید سیستم های خبره و هوشمند اسلامی باقرالعلوم(ع)
+
+
+
+ );
+}
+
+function SidebarItem({ icon, label, active = false, setFilters, name }) {
return (