diff --git a/app/src/features/support/SupportPage.tsx b/app/src/features/support/SupportPage.tsx index fc6201770c..cc55882794 100644 --- a/app/src/features/support/SupportPage.tsx +++ b/app/src/features/support/SupportPage.tsx @@ -1,37 +1,19 @@ -import { - mdiAccountSupervisor, - mdiAutoFix, - mdiCardAccountMailOutline, - mdiCheckDecagram, - mdiChevronLeft, - mdiChevronRight, - mdiDatabaseCog, - mdiEye, - mdiFileOutline, - mdiFolder, - mdiHome, - mdiInformationOutline, - mdiListBoxOutline, - mdiPaw, - mdiPineTreeVariant, - mdiWifiMarker -} from '@mdi/js'; +import { mdiChevronLeft, mdiChevronRight } from '@mdi/js'; import Icon from '@mdi/react'; import { Box, Button, Container, Divider, Paper, Stack, Typography } from '@mui/material'; -import AutocompleteSearchField from 'components/fields/AutocompleteSearch/AutocompleteSearchField'; import PageHeader from 'components/layout/PageHeader'; import CustomToggleButtonGroup from 'components/toolbar/CustomToggleButtonGroup'; import { useSearchParams } from 'hooks/useSearchParams'; -import { ReactNode, SetStateAction } from 'react'; -import { ISupportPageView, SupportPageParams, SupportPageView } from '../support/constants/SupportPageView'; -import { SupportOverview } from './content/overview/SupportOverview'; -import { SupportProjects } from './content/projects/SupportProjects'; -import { SupportObservations } from './content/projects/surveys/data/observations/SupportObservations'; -import { SupportData } from './content/projects/surveys/data/SupportData'; -import { SupportTelemetry } from './content/projects/surveys/data/telemetry/SupportTelemetry'; -import { SupportSampling } from './content/projects/surveys/sampling/SupportSampling'; -import { SupportSurveys } from './content/projects/surveys/SupportSurveys'; -import { SupportTeam } from './content/projects/team/SupportTeam'; +import { useMemo, useState } from 'react'; +import { + ISupportPageView, + SupportPageParams, + SupportPageView, + SupportPageViewMap, + SupportPageViews +} from './SupportPageView'; + +const VIEW_KEY = 'v'; /** * Returns information about how to use the app, definitions, and other resources for users. @@ -41,153 +23,52 @@ import { SupportTeam } from './content/projects/team/SupportTeam'; export const SupportPage = () => { const { searchParams, setSearchParams } = useSearchParams(); - const currentViewParam = searchParams.get('support_view'); - const currentView = (currentViewParam as SupportPageView) || SupportPageView.GENERAL; + // Initialize activeView based on the URL params + const [activeView, setActiveView] = useState( + (searchParams.get(VIEW_KEY) as SupportPageView) ?? SupportPageView.overview + ); - // Add nested structure - const views: ISupportPageView[] = [ - { - label: 'Overview', - value: SupportPageView.GENERAL, - icon: mdiHome, - children: [] - }, - { - label: 'Projects', - value: SupportPageView.PROJECTS, - icon: mdiFolder, - children: [ - { - label: 'Team', - value: SupportPageView.PROJECT_TEAM, - icon: mdiAccountSupervisor, - children: [] - }, - { - label: 'Surveys', - value: SupportPageView.SURVEYS, - icon: mdiListBoxOutline, - children: [ - { - label: 'Sampling', - value: SupportPageView.SAMPLING, - icon: mdiAutoFix, - children: [] - }, - { - label: 'Data', - value: SupportPageView.DATA, - icon: mdiDatabaseCog, - children: [ - { - label: 'Observations', - value: SupportPageView.OBSERVATIONS, - icon: mdiEye, - children: [] - }, - { - label: 'Telemetry', - value: SupportPageView.TELEMETRY, - icon: mdiWifiMarker, - children: [] - }, - { - label: 'Animals', - value: SupportPageView.ANIMALS, - icon: mdiPaw, - children: [] - }, - { - label: 'Habitat Features', - value: SupportPageView.HABITAT, - icon: mdiPineTreeVariant, - children: [] - } - ] - }, - { - label: 'Attachments', - value: SupportPageView.FILES, - icon: mdiFileOutline, - children: [] - }, - { - label: 'Metadata', - value: SupportPageView.METADATA, - icon: mdiInformationOutline, - children: [] - } - ] - } - ] - }, - { - label: 'Standards', - value: SupportPageView.DATA_STANDARDS, - icon: mdiCheckDecagram, - children: [] - }, - { - label: 'Contact', - value: SupportPageView.CONTACT, - icon: mdiCardAccountMailOutline, - children: [] + const handleViewChange = (view: SupportPageView) => { + if (view) { + setActiveView(view); + setSearchParams(searchParams.set(VIEW_KEY, view)); } - ]; + }; - // Finding the current view and navigating to the correct parent/child - const findView = (value: SupportPageView, views: ISupportPageView[]): ISupportPageView | null => { - for (const view of views) { - if (view.value === value) { - return view; - } - if (view.children.length > 0) { - const foundChild = findView(value, view.children); - if (foundChild) return foundChild; - } - } - return null; + // Recursively flattens child views + const flattenViews = (views: ISupportPageView[]): ISupportPageView[] => { + return views.flatMap((view) => [view, ...flattenViews(view.children ?? [])]); }; - const currentViewData = findView(currentView, views); - const currentIndex = views.findIndex((view) => view.value === currentView); - const nextView = views[(currentIndex + 1) % views.length]; - const prevView = views[(currentIndex - 1 + views.length) % views.length]; + // Find the current view object for its label, icon, children + const currentView = useMemo( + () => flattenViews(SupportPageViews).find((view) => view.value === activeView), + [activeView] + ); - const handleViewChange: React.Dispatch> = (value) => { - const newView = typeof value === 'function' ? value(currentView) : value; - setSearchParams(searchParams.set('support_view', newView)); - window.scrollTo(0, 0); - }; + // Sort views based on the order field + const orderedViews = useMemo( + () => SupportPageViews.flatMap((view) => [view, ...view.children]).sort((a, b) => a.order - b.order), + [] + ); - const dataMap: Partial> = { - [SupportPageView.GENERAL]: , - [SupportPageView.PROJECTS]: , - [SupportPageView.PROJECT_TEAM]: , - [SupportPageView.SURVEYS]: , - [SupportPageView.SAMPLING]: , - [SupportPageView.OBSERVATIONS]: , - [SupportPageView.TELEMETRY]: , - [SupportPageView.DATA]: - }; + const currentIndex = currentView ? orderedViews.findIndex((v) => v.value === currentView.value) : 0; + const prevView = orderedViews[currentIndex - 1] || null; + const nextView = orderedViews[currentIndex + 1] || null; + + // Get the JSX content to display for the activeView + const children = SupportPageViewMap[activeView]; return ( <> - {}} - onSearch={() => new Promise(() => 'a')} - fieldName="" - getOptionLabel={() => ''} - label="Search" - /> {/* Navigation Pane */} @@ -200,10 +81,10 @@ export const SupportPage = () => { {/* Content */} - {currentViewData?.label} + {currentView?.label} - {dataMap[currentView]} + {children} {/* Chevron Arrows */} @@ -211,7 +92,11 @@ export const SupportPage = () => { direction="row" alignItems="center" justifyContent={ - currentIndex === 0 ? 'flex-end' : currentIndex === views.length - 1 ? 'flex-start' : 'space-between' + currentIndex === 0 + ? 'flex-end' + : currentIndex === SupportPageViews.length - 1 + ? 'flex-start' + : 'space-between' } sx={{ width: '100%', '& .MuiButton-root': { fontWeight: 700 } }}> {currentIndex > 0 && ( @@ -221,7 +106,7 @@ export const SupportPage = () => { Previous )} - {currentIndex < views.length - 1 && ( + {currentIndex < SupportPageViews.length - 1 && (