Skip to content

Commit 4e24956

Browse files
Merge pull request #379 from jeafreezy/feat/user-profile-dashboard
Feat/user profile dashboard
2 parents 18c36df + d02e81b commit 4e24956

File tree

102 files changed

+2641
-474
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+2641
-474
lines changed

frontend/src/app/providers/auth-provider.tsx

+25-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type TAuthContext = {
1717
authenticateUser: (state: string, code: string) => Promise<void>;
1818
logout: () => void;
1919
isAuthenticated: boolean;
20+
setUser: (user: TUser) => void;
2021
};
2122

2223
// @ts-expect-error bad type definition
@@ -134,10 +135,32 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
134135
}
135136
};
136137

138+
/**
139+
* Poll the backend for the user profile information every 10 seconds.
140+
* This is majorly to keep the user profile information up to date, especially when the user is logged in.
141+
*/
142+
useEffect(() => {
143+
const intervalId = setInterval(() => {
144+
if (token) {
145+
authService.getUser().then(setUser).catch(showErrorToast);
146+
}
147+
}, 10000);
148+
149+
return () => clearInterval(intervalId);
150+
}, [token]);
151+
137152
return (
138153
<AuthContext.Provider
139-
// @ts-expect-error bad type definition
140-
value={{ token, user, authenticateUser, logout, isAuthenticated }}
154+
value={{
155+
// @ts-expect-error bad type definition
156+
token,
157+
// @ts-expect-error bad type definition
158+
user,
159+
authenticateUser,
160+
logout,
161+
isAuthenticated,
162+
setUser,
163+
}}
141164
>
142165
{children}
143166
</AuthContext.Provider>

frontend/src/app/router.tsx

+70-61
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
createBrowserRouter,
99
} from "react-router-dom";
1010
import { ModelsProvider } from "@/app/providers/models-provider";
11+
import { UserProfileLayout } from "@/layouts/user-profile-layout";
1112

1213
const router = createBrowserRouter([
1314
{
@@ -48,22 +49,7 @@ const router = createBrowserRouter([
4849
},
4950
},
5051
/**
51-
* Training dataset route
52-
*/
53-
{
54-
path: APPLICATION_ROUTES.TRAINING_DATASETS,
55-
lazy: async () => {
56-
const { TrainingDatasetsPage } = await import(
57-
"@/app/routes/training-datasets"
58-
);
59-
return { Component: TrainingDatasetsPage };
60-
},
61-
},
62-
/**
63-
* Training dataset route ends
64-
*/
65-
/**
66-
* Models details & list route starts
52+
* Models details & list route starts.
6753
*/
6854
{
6955
path: APPLICATION_ROUTES.MODEL_DETAILS,
@@ -93,7 +79,7 @@ const router = createBrowserRouter([
9379
},
9480
},
9581
/**
96-
* Models details & list route ends
82+
* Models details & list route ends.
9783
*/
9884
{
9985
element: (
@@ -103,7 +89,7 @@ const router = createBrowserRouter([
10389
),
10490
children: [
10591
/**
106-
* Model creation routes
92+
* Model creation routes.
10793
*/
10894
{
10995
path: APPLICATION_ROUTES.CREATE_NEW_MODEL,
@@ -172,11 +158,11 @@ const router = createBrowserRouter([
172158
},
173159
},
174160
/**
175-
* Model creation routes ends
161+
* Model creation routes ends.
176162
*/
177163

178164
/**
179-
* Model edit routes starts
165+
* Model edit routes starts.
180166
*/
181167
{
182168
path: APPLICATION_ROUTES.EDIT_MODEL_DETAILS,
@@ -247,33 +233,29 @@ const router = createBrowserRouter([
247233
],
248234
},
249235
/**
250-
* Model edit routes ends
236+
* Model edit routes ends.
251237
*/
252238
/**
253-
* Training dataset route starts
239+
* Datasets details route starts.
254240
*/
255241
{
256-
path: APPLICATION_ROUTES.TRAINING_DATASETS,
242+
path: APPLICATION_ROUTES.DATASET_DETAILS,
257243
lazy: async () => {
258-
const { TrainingDatasetsPage } = await import(
259-
"@/app/routes/training-datasets"
244+
const { TrainingDatasetsDetailPage } = await import(
245+
"@/app/routes/datasets/dataset-details"
260246
);
261247
return {
262-
Component: () => (
263-
<ProtectedRoute>
264-
<TrainingDatasetsPage />
265-
</ProtectedRoute>
266-
),
248+
Component: () => <TrainingDatasetsDetailPage />,
267249
};
268250
},
269251
},
270252

271253
/**
272-
* Training dataset route ends
254+
* Datasets details route ends.
273255
*/
274256

275257
/**
276-
* Start mapping route starts
258+
* Start mapping route starts.
277259
*/
278260
{
279261
path: APPLICATION_ROUTES.START_MAPPING,
@@ -291,40 +273,67 @@ const router = createBrowserRouter([
291273
},
292274
},
293275
/**
294-
* Start mapping route ends
276+
* Start mapping route ends.
295277
*/
296278

297279
/**
298-
* User account routes start
280+
* User account routes start.
299281
*/
300282
{
301-
path: APPLICATION_ROUTES.ACCOUNT_SETTINGS,
302-
lazy: async () => {
303-
const { UserAccountSettingsPage } = await import(
304-
"@/app/routes/account/settings"
305-
);
306-
return {
307-
Component: () => <UserAccountSettingsPage />,
308-
};
309-
},
310-
},
311-
{
312-
path: APPLICATION_ROUTES.ACCOUNT_MODELS,
313-
lazy: async () => {
314-
const { UserModelsPage } = await import(
315-
"@/app/routes/account/models"
316-
);
317-
return {
318-
Component: () => (
319-
<ProtectedRoute>
320-
<UserModelsPage />
321-
</ProtectedRoute>
322-
),
323-
};
324-
},
283+
element: (
284+
<ProtectedRoute>
285+
<UserProfileLayout />
286+
</ProtectedRoute>
287+
),
288+
children: [
289+
{
290+
path: APPLICATION_ROUTES.PROFILE_BASE,
291+
lazy: async () => {
292+
const { UserProfileOverviewPage } = await import(
293+
"@/app/routes/profile/overview"
294+
);
295+
return {
296+
Component: () => <UserProfileOverviewPage />,
297+
};
298+
},
299+
},
300+
{
301+
path: APPLICATION_ROUTES.PROFILE_SETTINGS,
302+
lazy: async () => {
303+
const { UserProfileSettingsPage } = await import(
304+
"@/app/routes/profile/settings"
305+
);
306+
return {
307+
Component: () => <UserProfileSettingsPage />,
308+
};
309+
},
310+
},
311+
{
312+
path: APPLICATION_ROUTES.PROFILE_MODELS,
313+
lazy: async () => {
314+
const { UserModelsPage } = await import(
315+
"@/app/routes/profile/models"
316+
);
317+
return {
318+
Component: () => <UserModelsPage />,
319+
};
320+
},
321+
},
322+
{
323+
path: APPLICATION_ROUTES.PROFILE_DATASETS,
324+
lazy: async () => {
325+
const { UserProfileDatasetsPage } = await import(
326+
"@/app/routes/profile/datasets"
327+
);
328+
return {
329+
Component: () => <UserProfileDatasetsPage />,
330+
};
331+
},
332+
},
333+
],
325334
},
326335
/**
327-
* User account routes ends
336+
* User account routes ends.
328337
*/
329338

330339
/**
@@ -344,7 +353,7 @@ const router = createBrowserRouter([
344353
*/
345354

346355
/**
347-
* 404 route
356+
* 404 route.
348357
*/
349358
{
350359
path: APPLICATION_ROUTES.NOTFOUND,
@@ -354,7 +363,7 @@ const router = createBrowserRouter([
354363
},
355364
},
356365
/**
357-
* Catch all route -> 404
366+
* Catch all route -> 404.
358367
*/
359368
{
360369
path: "*",

frontend/src/app/routes/account/settings.tsx

-5
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { PageUnderConstruction } from "@/components/errors";
2+
import { useParams } from "react-router-dom";
3+
4+
export const TrainingDatasetsDetailPage = () => {
5+
const { id } = useParams();
6+
console.log(id);
7+
return <PageUnderConstruction />;
8+
};

frontend/src/app/routes/models/model-details-card.tsx

+1-8
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ import {
1919
} from "@/features/models/components";
2020
import { useModelsContext } from "@/app/providers/models-provider";
2121

22-
23-
2422
export const ModelDetailsPage = () => {
2523
const {
2624
isOpened: isModelFilesDialogOpened,
@@ -89,8 +87,6 @@ export const ModelDetailsPage = () => {
8987
) : (
9088
<ModelDetailsProperties
9189
trainingId={data?.published_training as number}
92-
datasetId={data?.dataset?.id}
93-
baseModel={data.base_model}
9490
/>
9591
)}
9692
</ModelDetailsSection>
@@ -122,11 +118,8 @@ export const ModelDetailsPage = () => {
122118
</div>
123119
<TrainingHistoryTable
124120
modelId={data?.id as string}
125-
trainingId={data?.published_training as number}
121+
publishedTrainingId={data?.published_training as number}
126122
modelOwner={data?.user.username as string}
127-
datasetId={data?.dataset.id as number}
128-
baseModel={data?.base_model as string}
129-
tmsUrl={data?.dataset?.source_imagery}
130123
/>
131124
</ModelDetailsSection>
132125
</div>

frontend/src/app/routes/models/models-list.tsx

+9-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Head } from "@/components/seo";
44
import { LayoutView } from "@/enums";
55
import { MobileModelFiltersDialog } from "@/features/models/components/dialogs";
66
import { MODELS_CONTENT } from "@/constants";
7-
import { PAGE_LIMIT, Pagination } from "@/components/shared";
7+
import { OrderingFilter, Pagination, SearchFilter } from "@/components/shared";
88
import { PageHeader } from "@/features/models/components/";
99
import { useDialog } from "@/hooks/use-dialog";
1010
import { useEffect } from "react";
@@ -26,8 +26,6 @@ import {
2626
ClearFilters,
2727
DateRangeFilter,
2828
MobileFilter,
29-
OrderingFilter,
30-
SearchFilter,
3129
} from "@/features/models/components/filters";
3230

3331
import {
@@ -145,7 +143,14 @@ export const ModelsPage = () => {
145143
<div className="flex flex-col gap-y-1">
146144
<div className=" flex items-center justify-between w-full ">
147145
<div className="flex items-center justify-between w-full md:gap-x-4 gap-y-2 md:gap-y-0 md:w-auto">
148-
<SearchFilter updateQuery={updateQuery} query={query} />
146+
<SearchFilter
147+
updateQuery={updateQuery}
148+
query={query}
149+
placeholder={
150+
MODELS_CONTENT.models.modelsList.filtersSection
151+
.searchPlaceHolder
152+
}
153+
/>
149154
<CategoryFilter disabled={isPending} />
150155
{/* Mobile filters */}
151156
<div className="flex md:hidden items-center gap-x-4">
@@ -215,7 +220,6 @@ export const ModelsPage = () => {
215220
hasPrevPage={data?.hasPrev}
216221
disableNextPage={!data?.hasNext || isPlaceholderData}
217222
disablePrevPage={!data?.hasPrev}
218-
pageLimit={PAGE_LIMIT}
219223
query={query}
220224
updateQuery={updateQuery}
221225
isPlaceholderData={isPlaceholderData}
@@ -236,7 +240,6 @@ export const ModelsPage = () => {
236240
hasPrevPage={data?.hasPrev}
237241
disableNextPage={!data?.hasNext || isPlaceholderData}
238242
disablePrevPage={!data?.hasPrev}
239-
pageLimit={PAGE_LIMIT}
240243
query={query}
241244
updateQuery={updateQuery}
242245
isPlaceholderData={isPlaceholderData}

frontend/src/app/routes/not-found.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export const PageNotFound = () => {
1111
);
1212

1313
const trainingDatasetNotFound = location.state?.from.includes(
14-
APPLICATION_ROUTES.TRAINING_DATASETS,
14+
APPLICATION_ROUTES.DATASETS,
1515
);
1616

1717
const navigate = useNavigate();
@@ -71,7 +71,7 @@ export const PageNotFound = () => {
7171
modelNotFound
7272
? APPLICATION_ROUTES.MODELS
7373
: trainingDatasetNotFound
74-
? APPLICATION_ROUTES.TRAINING_DATASETS
74+
? APPLICATION_ROUTES.DATASETS
7575
: APPLICATION_ROUTES.HOMEPAGE,
7676
);
7777
}}

0 commit comments

Comments
 (0)