diff --git a/frontend/.env.sample b/frontend/.env.sample
index 9cb470a6f..cf18ebae6 100644
--- a/frontend/.env.sample
+++ b/frontend/.env.sample
@@ -6,7 +6,12 @@ VITE_BASE_API_URL = "http://localhost:8000/api/v1/"
# Authentication: "legacy" or "hanko"
VITE_AUTH_PROVIDER = "legacy"
-# VITE_HANKO_URL = "https://dev.login.hotosm.org"
+
+
+# The Hanko authentication URL for user authentication.
+# Data type: String (e.g., "https://dev.login.hotosm.org").
+# Default value: "https://dev.login.hotosm.org".
+VITE_HANKO_URL = "https://dev.login.hotosm.org"
# The matomo application ID.
# Data type: Positive Integer (e.g., 0).
@@ -225,35 +230,35 @@ VITE_MAXIMUM_ORTHO_SKEW_TOLEARANCE_AND_MAX_ANGLE_CHANGE_IN_DEGREES = 45
# Data type: String (e.g., "#247DCACC").
# Note: Colors must be hex codes or valid colors. e.g red, green, #fff.
# Default value: "#D73434".
-PREDICTIONS_RESULTS_POINT_FILL_COLOR = "#34D77C"
+VITE_PREDICTIONS_RESULTS_POINT_FILL_COLOR = "#34D77C"
# The outline color for the prediction requests points.
# Data type: String (e.g., "#247DCACC").
# Note: Colors must be hex codes or valid colors. e.g red, green, #fff.
# Default value: "#D73434".
-PREDICTIONS_RESULTS_POINT_OUTLINE_COLOR = "#34D77C"
+VITE_PREDICTIONS_RESULTS_POINT_OUTLINE_COLOR = "#34D77C"
#The URL to fetch the latest fair updates.
# Data type: String
# Default value: "https://raw.githubusercontent.com/hotosm/fAIr/develop/docs/assets/fair-updates.json".
-FAIR_VIDEO_UPDATES_URL = "https://raw.githubusercontent.com/hotosm/fAIr/develop/docs/assets/fair-updates.json";
+VITE_FAIR_VIDEO_UPDATES_URL = "https://raw.githubusercontent.com/hotosm/fAIr/develop/docs/assets/fair-updates.json";
#FAIR Youtube Backup Video URL to use when invalid youtube url is returned.
# Data type: String
# Default value: "https://www.youtube.com/embed/N2_9Bvm05_0?si=to_2aoeRCW3APmmZ".
-FAIR_VIDEO_BACKUP_URL = "https://www.youtube.com/embed/N2_9Bvm05_0?si=to_2aoeRCW3APmmZ"
+VITE_FAIR_VIDEO_BACKUP_URL = "https://www.youtube.com/embed/N2_9Bvm05_0?si=to_2aoeRCW3APmmZ"
# The number of required MapSwipe validations for a prediction to be considered valid.
# Data type: Positive Integer (e.g., 4).
# Default value: 4.
-MAPSWIPE_VERIFICATION_NUMBER = 4
+VITE_MAPSWIPE_VERIFICATION_NUMBER = 4
# The group size for MapSwipe projects.
# Data type: Positive Integer (e.g., 25).
# Default value: 25.
-MAPSWIPE_GROUP_SIZE = 25
+VITE_MAPSWIPE_GROUP_SIZE = 25
# The Hanko authentication token for user authentication. ####### ONLY NEEDED IN DEVELOPMENT ENVIRONMENT. ########
diff --git a/frontend/src/app/router.tsx b/frontend/src/app/router.tsx
index 042ac7e7d..c52460e42 100644
--- a/frontend/src/app/router.tsx
+++ b/frontend/src/app/router.tsx
@@ -1,4 +1,5 @@
import { APPLICATION_ROUTES } from "@/constants";
+import { isNavigationRouteEnabled } from "@/constants/general";
import { MainErrorFallback } from "@/components/errors";
import {
ModelFormsLayout,
@@ -10,13 +11,34 @@ import {
Navigate,
RouterProvider,
createBrowserRouter,
+ useLocation,
} from "react-router-dom";
import { ModelsProvider } from "@/app/providers/models-provider";
import { NuqsAdapter } from "nuqs/adapters/react-router/v6";
+const RouteAvailabilityGuard = ({ children }: React.PropsWithChildren) => {
+ const location = useLocation();
+
+ if (!isNavigationRouteEnabled(location.pathname)) {
+ return (
+
+ );
+ }
+
+ return children;
+};
+
const router = createBrowserRouter([
{
- element: ,
+ element: (
+
+
+
+ ),
children: [
/**
* Landing page route starts
diff --git a/frontend/src/components/ui/banner/banner.tsx b/frontend/src/components/ui/banner/banner.tsx
index 77a12b7cc..6a6fe0bf8 100644
--- a/frontend/src/components/ui/banner/banner.tsx
+++ b/frontend/src/components/ui/banner/banner.tsx
@@ -12,7 +12,7 @@ type TBannerResponse = {
const fetchBanner = async (): Promise => {
const { data } = await apiClient.get(API_ENDPOINTS.GET_BANNER);
- return data;
+ return data.results;
};
const Banner = () => {
diff --git a/frontend/src/config/env.ts b/frontend/src/config/env.ts
index f5dc870d9..3ba7c02ca 100644
--- a/frontend/src/config/env.ts
+++ b/frontend/src/config/env.ts
@@ -105,8 +105,8 @@ export const ENVS = {
PREDICTIONS_RESULTS_POINT_OUTLINE_COLOR:
env.VITE_PREDICTIONS_RESULTS_POINT_OUTLINE_COLOR,
- FAIR_YOUTUBE_UPDATES_URL: env.FAIR_VIDEO_UPDATES_URL,
- FAIR_VIDEO_BACKUP_URL: env.FAIR_VIDEO_BACKUP_URL,
+ FAIR_YOUTUBE_UPDATES_URL: env.VITE_FAIR_VIDEO_UPDATES_URL,
+ FAIR_VIDEO_BACKUP_URL: env.VITE_FAIR_VIDEO_BACKUP_URL,
MAPSWIPE_VERIFICATION_NUMBER: env.VITE_MAPSWIPE_VERIFICATION_NUMBER,
MAPSWIPE_GROUP_SIZE: env.VITE_MAPSWIPE_GROUP_SIZE,
FAIR_STAC_CATALOG_BASE_URL: env.VITE_FAIR_STAC_CATALOG_BASE_URL,
diff --git a/frontend/src/constants/general.ts b/frontend/src/constants/general.ts
index af25deeae..97282bee0 100644
--- a/frontend/src/constants/general.ts
+++ b/frontend/src/constants/general.ts
@@ -6,12 +6,12 @@ export const navLinks: TNavBarLinks = [
{
title: SHARED_CONTENT.navbar.routes.exploreModels,
href: APPLICATION_ROUTES.MODELS,
- active: true,
+ active: false,
},
{
title: SHARED_CONTENT.navbar.routes.exploreDatasets,
href: APPLICATION_ROUTES.DATASETS,
- active: true,
+ active: false,
children: [
{
title: "Training Datasets",
@@ -40,6 +40,21 @@ export const navLinks: TNavBarLinks = [
},
];
+/**
+ * Determines whether a URL is available according to the navigation config.
+ *
+ * A disabled top-level item also disables every route below its URL. This keeps
+ * a hidden navigation item from still being accessible by pasting its URL.
+ */
+export const isNavigationRouteEnabled = (pathname: string): boolean => {
+ return !navLinks.some((link) => {
+ if (link.active || !link.href) return false;
+
+ const route = link.href.replace(/\/$/, "");
+ return pathname === route || pathname.startsWith(`${route}/`);
+ });
+};
+
type TFooterGroupLinks = {
groupOne: TFooterLinks;
groupTwo: TFooterLinks;
@@ -50,17 +65,17 @@ export const footerLinks: TFooterGroupLinks = {
{
title: "explore models",
route: APPLICATION_ROUTES.MODELS,
- active: true,
+ active: false,
},
{
title: "Training datasets",
route: APPLICATION_ROUTES.DATASETS,
- active: true,
+ active: false,
},
{
title: "AI Predictions",
route: APPLICATION_ROUTES.AI_PREDICTIONS,
- active: true,
+ active: false,
},
{
title: "learn",