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