diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml
index 9e08820..e82f5a2 100644
--- a/.github/workflows/node.js.yml
+++ b/.github/workflows/node.js.yml
@@ -48,5 +48,6 @@ jobs:
- run: pnpm install
- name: Build the application
env:
- BACKEND_URL: "http://localhost:8080"
+ NEXT_PUBLIC_API_URL: "http://localhost:8080"
+ BACK_END_URL: "http://localhost:8080"
run: pnpm build
diff --git a/README.md b/README.md
index 74fdb5e..6a8ef76 100644
--- a/README.md
+++ b/README.md
@@ -110,10 +110,10 @@ Set up the application environment variables by running the following script:
scripts/init_environments.sh
```
-This script generates environment variables, including BACKEND_URL, to establish the communication between the client and server. Example
+This script generates environment variables, including NEXT_PUBLIC_API_URL, to establish the communication between the client and server. Example
```
-BACKEND_URL=http://localhost:8080
+NEXT_PUBLIC_API_URL=http://localhost:8080
```
We recommend running the `scripts/all.sh` script, as it streamlines the process by checking your environment settings and performing all necessary configurations, removing the need to execute multiple scripts manually.
diff --git a/next.config.mjs b/next.config.mjs
index a87e580..8b1fd47 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -6,7 +6,7 @@ const nextConfig = {
fallback: [
{
source: "/api/:path*",
- destination: `${process.env.BACKEND_URL}/api/:path*`,
+ destination: `${process.env.NEXT_PUBLIC_API_URL}/api/:path*`,
},
],
};
diff --git a/package.json b/package.json
index 3fedb04..ec28c9e 100644
--- a/package.json
+++ b/package.json
@@ -63,6 +63,7 @@
"nanoid": "^5.0.9",
"next": "^15.1.2",
"next-auth": "5.0.0-beta.25",
+ "next-runtime-env": "^3.2.2",
"next-themes": "^0.4.4",
"nuqs": "^2.2.3",
"react": "^19.0.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f770a3f..cbeb93a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -169,6 +169,9 @@ importers:
next-auth:
specifier: 5.0.0-beta.25
version: 5.0.0-beta.25(next@15.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)
+ next-runtime-env:
+ specifier: ^3.2.2
+ version: 3.2.2(next@15.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)
next-themes:
specifier: ^0.4.4
version: 0.4.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@@ -4254,6 +4257,15 @@ packages:
nodemailer:
optional: true
+ next-runtime-env@3.2.2:
+ resolution:
+ {
+ integrity: sha512-S5S6NxIf3XeaVc9fLBN2L5Jzu+6dLYCXeOaPQa1RzKRYlG2BBayxXOj6A4VsciocyNkJMazW1VAibtbb1/ZjAw==,
+ }
+ peerDependencies:
+ next: ^14
+ react: ^18
+
next-themes@0.4.4:
resolution:
{
@@ -8373,6 +8385,11 @@ snapshots:
next: 15.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react: 19.0.0
+ next-runtime-env@3.2.2(next@15.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0):
+ dependencies:
+ next: 15.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ react: 19.0.0
+
next-themes@0.4.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
react: 19.0.0
diff --git a/scripts/docker_deployment.sh b/scripts/docker_deployment.sh
index 1a596ff..2854f2e 100755
--- a/scripts/docker_deployment.sh
+++ b/scripts/docker_deployment.sh
@@ -24,14 +24,14 @@ docker tag ${IMAGE_NAME} ${REMOTE_REPO}:${TAG}
docker tag ${IMAGE_NAME} ${REMOTE_REPO}:latest
# Step 3: Log in to the Docker repository (Docker Hub by default)
-echo "Logging into Docker repository..."
-docker login || { echo "Login failed"; exit 1; }
-
-# Step 4: Push both tags to the remote repository
-echo "Pushing Docker image to remote repository with tag '${TAG}'..."
-docker push ${REMOTE_REPO}:${TAG}
-
-echo "Pushing Docker image to remote repository with tag 'latest'..."
-docker push ${REMOTE_REPO}:latest
-
-echo "Docker image has been pushed successfully with tags '${TAG}' and 'latest'."
+#echo "Logging into Docker repository..."
+#docker login || { echo "Login failed"; exit 1; }
+#
+## Step 4: Push both tags to the remote repository
+#echo "Pushing Docker image to remote repository with tag '${TAG}'..."
+#docker push ${REMOTE_REPO}:${TAG}
+#
+#echo "Pushing Docker image to remote repository with tag 'latest'..."
+#docker push ${REMOTE_REPO}:latest
+#
+#echo "Docker image has been pushed successfully with tags '${TAG}' and 'latest'."
diff --git a/scripts/init_environments.sh b/scripts/init_environments.sh
index 710c00d..9d5c20b 100755
--- a/scripts/init_environments.sh
+++ b/scripts/init_environments.sh
@@ -33,7 +33,8 @@ while true; do
done
# Append to the .env.local file
-echo "BACKEND_URL=\"$backend_server\"" >> "$output_file"
+echo "NEXT_PUBLIC_API_URL=\"$backend_server\"" >> "$output_file"
+echo "BACK_END_URL=\"$backend_server\"" >> "$output_file"
# Run npx auth and append its output to .env
diff --git a/src/app/(auth)/login/page.tsx b/src/app/(auth)/login/page.tsx
index 7211c0c..9d90135 100644
--- a/src/app/(auth)/login/page.tsx
+++ b/src/app/(auth)/login/page.tsx
@@ -1,6 +1,8 @@
import LoginForm from "@/components/auth/login-form";
+import { BACK_END_URL } from "@/lib/constants";
-const LoginPage = () => {
+const LoginPage = async () => {
+ console.log(`BACK_END ${BACK_END_URL}`);
return ;
};
export default LoginPage;
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index c36de8a..bbb0cdd 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -3,11 +3,10 @@ import "./theme.css";
import type { Metadata } from "next";
import { Inter } from "next/font/google";
+import { PublicEnvScript } from "next-runtime-env";
-import AutoInitBackendApi from "@/components/init-api-backend";
import { Toaster } from "@/components/ui/toaster";
import { TooltipProvider } from "@/components/ui/tooltip";
-import { setBackendUrl, setBaseUrl } from "@/lib/runtime-variables";
import { ErrorProvider } from "@/providers/error-provider";
import ReactQueryProvider from "@/providers/react-query-provider";
import { ThemeProvider } from "@/providers/theme-provider";
@@ -19,44 +18,21 @@ export const metadata: Metadata = {
description: "FlowInquiry dashboard",
};
-const RootLayout = async ({
- children,
-}: Readonly<{
- children: React.ReactNode;
-}>) => {
- const backendUrl = process.env.BACKEND_URL;
- if (!backendUrl) {
- throw new Error("BACKEND_URL is not defined in the environment");
- }
- setBackendUrl(backendUrl);
-
- // Base url is the mandatory field in environments except local
- const baseUrl = process.env.BASE_URL;
- setBaseUrl(baseUrl);
-
+const RootLayout = async ({ children }: { children: React.ReactNode }) => {
return (
+
FlowInquiry - Ticket Management
- {/* Favicon for modern browsers */}
- {/* Fallback favicon for older browsers */}
-
-
- {children}
-
+ {children}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index def249f..9ab5d0d 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,13 +1,7 @@
-import { redirect } from "next/navigation";
+import { Home } from "@/components/home";
-import { auth } from "@/auth";
+const Page = async () => {
+ return ;
+};
-export default async function Home() {
- const session = await auth();
- if (!session) {
- console.warn("No authentication. Redirect to the login page ...");
- redirect("/login");
- } else {
- redirect("/portal");
- }
-}
+export default Page;
diff --git a/src/auth.ts b/src/auth.ts
index 1b90442..8cebbc6 100644
--- a/src/auth.ts
+++ b/src/auth.ts
@@ -18,8 +18,7 @@ export const { handlers, auth } = NextAuth({
if (!credentials) {
throw new Error("Invalid credentials");
}
- const user = await apiAuthSignIn(credentials);
- return user;
+ return await apiAuthSignIn(credentials);
},
}),
],
diff --git a/src/components/admin-panel/content-layout.tsx b/src/components/admin-panel/content-layout.tsx
index 4a93cf7..64408aa 100644
--- a/src/components/admin-panel/content-layout.tsx
+++ b/src/components/admin-panel/content-layout.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import { Navbar } from "@/components/admin-panel/navbar";
interface ContentLayoutProps {
diff --git a/src/components/admin-panel/user-nav.tsx b/src/components/admin-panel/user-nav.tsx
index 3b0be71..eeab491 100644
--- a/src/components/admin-panel/user-nav.tsx
+++ b/src/components/admin-panel/user-nav.tsx
@@ -30,7 +30,7 @@ import {
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
-import { getApiUrl, getBaseUrl } from "@/lib/runtime-variables";
+import { API_URL } from "@/lib/constants";
export function UserNav() {
const { data: session } = useSession();
@@ -50,7 +50,7 @@ export function UserNav() {
signOut({ redirectTo: getBaseUrl() })}
+ onClick={() => signOut()}
>
Sign out
@@ -111,12 +111,10 @@ export function UserNav() {
- {/* Logo */}
- {/* Title and Description */}
FlowInquiry
diff --git a/src/components/forms/profile-form.tsx b/src/components/forms/profile-form.tsx
index 24ed536..6c054fa 100644
--- a/src/components/forms/profile-form.tsx
+++ b/src/components/forms/profile-form.tsx
@@ -40,7 +40,7 @@ import {
findUserById,
updateUser,
} from "@/lib/actions/users.action";
-import { getApiUrl } from "@/lib/runtime-variables";
+import { API_URL } from "@/lib/constants";
import { useError } from "@/providers/error-provider";
import { UserDTOSchema } from "@/types/users";
@@ -159,7 +159,7 @@ export const ProfileForm = () => {
{
+ const session = getSession();
+ if (!session) {
+ redirect("/login");
+ } else {
+ redirect("/portal");
+ }
+};
diff --git a/src/components/init-api-backend.tsx b/src/components/init-api-backend.tsx
deleted file mode 100644
index 8ff9a66..0000000
--- a/src/components/init-api-backend.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-"use client";
-
-import { useEffect } from "react";
-
-import { initializeBaseUrlOnClient } from "@/lib/runtime-variables";
-
-const AutoInitBackendApi = () => {
- useEffect(() => {
- initializeBaseUrlOnClient();
- }, []);
-
- return null; // This component is only for initialization
-};
-
-export default AutoInitBackendApi;
diff --git a/src/components/shared/avatar-display.tsx b/src/components/shared/avatar-display.tsx
index 5a1082d..4d8ab52 100644
--- a/src/components/shared/avatar-display.tsx
+++ b/src/components/shared/avatar-display.tsx
@@ -5,7 +5,7 @@ import React from "react";
import DefaultTeamLogo from "@/components/teams/team-logo";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import DefaultUserLogo from "@/components/users/user-logo";
-import { getApiUrl } from "@/lib/runtime-variables";
+import { API_URL } from "@/lib/constants";
interface AvatarDisplayProps {
imageUrl?: string | null;
@@ -25,7 +25,7 @@ export const AvatarDisplay: React.FC = ({
return (
{fallbackContent}
diff --git a/src/components/teams/team-form.tsx b/src/components/teams/team-form.tsx
index 3cedf64..3abef6e 100644
--- a/src/components/teams/team-form.tsx
+++ b/src/components/teams/team-form.tsx
@@ -31,8 +31,8 @@ import {
findTeamById,
updateTeam,
} from "@/lib/actions/teams.action";
+import { API_URL } from "@/lib/constants";
import { obfuscate } from "@/lib/endecode";
-import { getApiUrl } from "@/lib/runtime-variables";
import { validateForm } from "@/lib/validator";
import { useError } from "@/providers/error-provider";
import { TeamDTO, TeamDTOSchema } from "@/types/teams";
@@ -175,7 +175,7 @@ export const TeamForm = ({ teamId }: { teamId: number | undefined }) => {
{
{
(
options.body = JSON.stringify(data);
}
- const apiUrl = getApiUrl();
-
try {
+ const apiUrl =
+ securityMode === SecurityMode.CLIENT_SECURE ? API_URL : BACK_END_URL;
const response = await fetch(`${apiUrl}${url}`, options);
if (response.ok) {
diff --git a/src/lib/auth.ts b/src/lib/auth.ts
index 166b8de..f6a0ee1 100644
--- a/src/lib/auth.ts
+++ b/src/lib/auth.ts
@@ -1,8 +1,10 @@
+import { BACK_END_URL } from "@/lib/constants";
+
export default async function apiAuthSignIn(
credentials: Partial> | undefined,
) {
try {
- const response = await fetch(`${process.env.BACKEND_URL}/api/login`, {
+ const response = await fetch(`${BACK_END_URL}/api/login`, {
method: "POST",
headers: {
"Content-Type": "application/json",
diff --git a/src/lib/constants.ts b/src/lib/constants.ts
new file mode 100644
index 0000000..f712eb5
--- /dev/null
+++ b/src/lib/constants.ts
@@ -0,0 +1,4 @@
+import { env } from "next-runtime-env";
+
+export const API_URL = env("NEXT_PUBLIC_API_URL");
+export const BACK_END_URL = process.env.BACK_END_URL;
diff --git a/src/lib/runtime-variables.ts b/src/lib/runtime-variables.ts
deleted file mode 100644
index de02d8b..0000000
--- a/src/lib/runtime-variables.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * The backend url that nextjs server side initiates the request to FlowInquiry backend service
- */
-let backendUrl: string | null = null;
-
-/**
- * The base URL is the address that the Next.js client-side uses to initiate requests to the FlowInquiry service. Note that the
- * base URL and the back-end URL are significantly different. The base URL is accessible from the client side, enabling API communication,
- * while the back-end URL might only be accessible within the FlowInquiry cluster and not directly exposed to the client.
- */
-let baseUrl: string | undefined = undefined;
-
-// Function to set the `BACKEND_API`
-export const setBackendUrl = (url: string) => {
- backendUrl = url;
-};
-
-export const setBaseUrl = (url?: string) => {
- baseUrl = url;
-};
-
-// Function to initialize `BASE_URL` on the client
-export const initializeBaseUrlOnClient = () => {
- if (typeof window !== "undefined" && window.BASE_URL) {
- setBaseUrl(window.BASE_URL);
- } else {
- console.warn("Base url API is not defined on the client.");
- }
-};
-
-// Function to get the `BACKEND_URL`
-export const getBackendUrl = (): string => {
- return backendUrl!;
-};
-
-export const getBaseUrl = (): string | undefined => {
- return baseUrl;
-};
-
-export const getApiUrl = () => {
- const baseUrl = getBaseUrl();
- return baseUrl ? baseUrl : getBackendUrl();
-};