diff --git a/apps/web/app/dashboard/page.tsx b/apps/web/app/dashboard/page.tsx
index 31419879..56919027 100644
--- a/apps/web/app/dashboard/page.tsx
+++ b/apps/web/app/dashboard/page.tsx
@@ -1,78 +1,18 @@
-import { GenerateImage } from "@/components/GenerateImage";
-import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
-import { Train } from "@/components/Train";
-import { Packs } from "@/components/Packs";
-import { Camera } from "@/components/Camera";
import { redirect } from "next/navigation";
import { auth } from "@clerk/nextjs/server";
+import { DashboardClient } from "@/components/DashboardClient";
+import { getPacks } from '../../components/Packs';
export const dynamic = "force-dynamic";
export default async function DashboardPage() {
const { userId } = await auth();
+ const packs = await getPacks();
if (!userId) {
redirect("/");
}
return (
-
-
-
-
-
- Camera
-
-
- GenerateImages
-
-
- Packs
-
-
- TrainModel
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
);
}
diff --git a/apps/web/components/DashboardClient.tsx b/apps/web/components/DashboardClient.tsx
new file mode 100644
index 00000000..6db2c89e
--- /dev/null
+++ b/apps/web/components/DashboardClient.tsx
@@ -0,0 +1,79 @@
+"use client"
+import { GenerateImage } from "@/components/GenerateImage";
+import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
+import { Train } from "@/components/Train";
+import { PacksClient } from "./PacksClient";
+import { Camera } from "@/components/Camera";
+import { Provider } from "react-redux";
+import store from "../store/store";
+import { TPack } from './PackCard';
+
+export function DashboardClient({ packs }: { packs: TPack[]}){
+ return(
+
+
+
+
+
+
+ Camera
+
+
+ GenerateImages
+
+
+ Packs
+
+
+ TrainModel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+
+
+
diff --git a/apps/web/components/Packs.tsx b/apps/web/components/Packs.tsx
index 0325dc1d..eb042ba9 100644
--- a/apps/web/components/Packs.tsx
+++ b/apps/web/components/Packs.tsx
@@ -3,7 +3,7 @@ import { TPack } from "./PackCard";
import axios from "axios";
import { PacksClient } from "./PacksClient";
-async function getPacks(): Promise {
+export async function getPacks(): Promise {
const res = await axios.get(`${BACKEND_URL}/pack/bulk`);
return res.data.packs ?? [];
}
diff --git a/apps/web/components/Train.tsx b/apps/web/components/Train.tsx
index 7fb5b87d..675c6cc3 100644
--- a/apps/web/components/Train.tsx
+++ b/apps/web/components/Train.tsx
@@ -38,6 +38,9 @@ import {
CarouselPrevious,
} from "@/components/ui/carousel";
import JSZip from "jszip";
+import { useSelector, useDispatch } from "react-redux";
+import { setModelIdStore, setModelTrainingStore } from "../store/trainModelSlice";
+import { RootState } from "../store/store";
interface UploadedFile {
name: string;
@@ -64,6 +67,18 @@ export function Train() {
const [uploadProgress, setUploadProgress] = useState(0);
const [modelId, setModelId] = useState(null);
const [trainingStatus, setTrainingStatus] = useState(null);
+ const modelIdStore = useSelector( (state: RootState) => state.trainModelReducer.modelIdStore );
+ const modelTrainingStore = useSelector( (state: RootState) => state.trainModelReducer.modelTrainingStore );
+ const dispatch = useDispatch();
+
+ // Check upon the component mount if any model is already training
+ useEffect( () => {
+ console.log("inside useEffect 1")
+ if(modelTrainingStore && modelIdStore){
+ setModelId(modelIdStore);
+ setModelTraining(modelTrainingStore);
+ }
+ }, [] )
// Check training status periodically if we have a modelId
useEffect(() => {
@@ -94,7 +109,9 @@ export function Train() {
toast.error("Model training failed. Please try again.");
}
setModelId(null);
+ dispatch(setModelIdStore(null));
setModelTraining(false);
+ dispatch(setModelTrainingStore(false));
}
}
} catch (error) {
@@ -143,6 +160,7 @@ export function Train() {
try {
const token = await getToken();
setModelTraining(true);
+ dispatch(setModelTrainingStore(true));
const response = await axios.post(`${BACKEND_URL}/ai/training`, input, {
headers: { Authorization: `Bearer ${token}` },
@@ -150,12 +168,14 @@ export function Train() {
if (response.data.modelId) {
setModelId(response.data.modelId);
+ dispatch(setModelIdStore(response.data.modelId));
toast.success(
"Model training started! This will take approximately 20 minutes."
);
} else {
toast.error("Failed to start model training");
setModelTraining(false);
+ dispatch(setModelTrainingStore(false));
}
} catch (error) {
console.error("Training error:", error);
@@ -164,6 +184,7 @@ export function Train() {
"Failed to start model training"
);
setModelTraining(false);
+ dispatch(setModelTrainingStore(false));
}
}
diff --git a/apps/web/package.json b/apps/web/package.json
index 2469cc01..3833fa01 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -23,6 +23,7 @@
"@radix-ui/react-tabs": "^1.1.3",
"@radix-ui/react-toast": "^1.2.6",
"@radix-ui/react-tooltip": "^1.1.8",
+ "@reduxjs/toolkit": "^2.8.2",
"@repo/ui": "*",
"@stripe/stripe-js": "^5.6.0",
"@tailwindcss/postcss": "^4.0.6",
@@ -43,6 +44,7 @@
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-hot-toast": "^2.5.1",
+ "react-redux": "^9.2.0",
"tailwind-merge": "^3.0.1",
"tailwindcss": "^4.0.6",
"tailwindcss-animate": "^1.0.7"
diff --git a/apps/web/store/store.ts b/apps/web/store/store.ts
new file mode 100644
index 00000000..430f851c
--- /dev/null
+++ b/apps/web/store/store.ts
@@ -0,0 +1,11 @@
+import { configureStore } from "@reduxjs/toolkit";
+import trainModelReducer from "./trainModelSlice";
+
+const store = configureStore({
+ reducer: {
+ trainModelReducer: trainModelReducer
+ }
+})
+
+export default store;
+export type RootState = ReturnType;
\ No newline at end of file
diff --git a/apps/web/store/trainModelSlice.ts b/apps/web/store/trainModelSlice.ts
new file mode 100644
index 00000000..739e01c3
--- /dev/null
+++ b/apps/web/store/trainModelSlice.ts
@@ -0,0 +1,27 @@
+import { createSlice, PayloadAction } from "@reduxjs/toolkit";
+
+type initialStateType = {
+ modelIdStore: null|string ,
+ modelTrainingStore: boolean
+}
+
+const initialState: initialStateType = {
+ modelIdStore: null,
+ modelTrainingStore: false
+}
+
+const trainModelSlice = createSlice({
+ name: 'trainModelSlice',
+ initialState: initialState,
+ reducers: {
+ setModelIdStore: ( state, action: PayloadAction ) => {
+ state.modelIdStore = action.payload
+ },
+ setModelTrainingStore: (state, action: PayloadAction) => {
+ state.modelTrainingStore = action.payload
+ }
+ }
+})
+
+export default trainModelSlice.reducer;
+export const { setModelIdStore, setModelTrainingStore } = trainModelSlice.actions;
\ No newline at end of file
diff --git a/bun.lockb b/bun.lockb
index 90f6882e..f17e7471 100755
Binary files a/bun.lockb and b/bun.lockb differ