diff --git a/frontend/src/components/sidebarMenu/index.tsx b/frontend/src/components/sidebarMenu/index.tsx index 3ecb8bb..4488b0e 100644 --- a/frontend/src/components/sidebarMenu/index.tsx +++ b/frontend/src/components/sidebarMenu/index.tsx @@ -4,7 +4,6 @@ import CustomButton from 'components/button'; import SidebarButtonPrimary from './sidebarButtonPrimary'; import SidebarButtonSecondary from './sidebarButtonSecondary'; import { - MdSpoke, MdChevronRight, MdSupport, MdOutlineOpenInNew, @@ -15,8 +14,9 @@ import { import { ReactComponent as Flow } from 'assets/icons/Flow Icon.svg'; import { ReactComponent as CrumpetLogo } from 'assets/images/Crumpet Logo Oxford.svg'; import { Fragment, useState } from 'react'; -import TextInput from 'components/textInput'; import { CreateProjectModal } from 'features/projects/components/CreateProjectModal'; +import { useProjectsStore } from 'features/projects/stores/useProjectsStore'; +import { getFirstLetter } from 'utils'; const environments = [ { id: 1, name: 'Development' }, @@ -35,9 +35,9 @@ interface SidebarMenuProps { } const SidebarMenu = ({ projects }: SidebarMenuProps) => { - //TODO: Use custom modal and encapsulate logic into its own hook - const [projectName, setProjectName] = useState(''); const [isOpen, setIsOpen] = useState(false); + const { selectedProject } = useProjectsStore(); + const isLoadingState = ['initial', 'loading', 'hasError'].includes(selectedProject.state); function closeModal() { setIsOpen(false); @@ -64,19 +64,12 @@ const SidebarMenu = ({ projects }: SidebarMenuProps) => { console.log('Clicked Button'); }, }, - { - label: 'Segments', - icon: () => , - onClick: () => { - console.log('Clicked Button'); - }, - }, ]; return ( <>
@@ -84,7 +77,7 @@ const SidebarMenu = ({ projects }: SidebarMenuProps) => {
Crumpet
-
+
{ButtonList.map((button, index) => ( {
-
+
} label="Support" @@ -116,15 +109,27 @@ const SidebarMenu = ({ projects }: SidebarMenuProps) => { {({ open }) => ( <> - -
-
- C + {isLoadingState ? ( + // Render pulsing grey rectangle for initial, loading, and hasError states +
+
+
+
+ ) : ( +
+
+ {getFirstLetter( + selectedProject.state === 'hasData' ? selectedProject.data.name : null, + )} +
+ + {selectedProject.state === 'hasData' ? selectedProject.data.name : ''} +
- Crumpet -
+ )} ; fetchProjects: (config: Configuration) => void; setSelectedProject: (projectId: number) => void; + fetchAndSelectProject: (config: Configuration) => void; createProject: (name: string, config: Configuration) => void; }; @@ -29,6 +30,18 @@ export const useProjectsStore = create((set, get) => ({ } } }, + fetchAndSelectProject: (config: Configuration) => { + set(state => ({ projects: ApiState.loading() })); + new ProjectsApi(config) + .listProjects() + .then(res => + set(state => ({ + projects: ApiState.hasData(res.data), + selectedProject: ApiState.hasData(res.data[0]), + })), + ) + .catch(err => set(state => ({ projects: ApiState.hasError(err) }))); + }, createProject: async (name: string, config: Configuration) => { const res = await new ProjectsApi(config).createProject({ name: name }); set(state => ({ selectedProject: ApiState.hasData(res.data) })); diff --git a/frontend/src/pages/root/index.tsx b/frontend/src/pages/root/index.tsx index 1dc79ce..8f34430 100644 --- a/frontend/src/pages/root/index.tsx +++ b/frontend/src/pages/root/index.tsx @@ -6,12 +6,12 @@ import { Outlet, useNavigate } from 'react-router-dom'; const Root = () => { const { config } = useApiConfig(); - const { projects, fetchProjects, setSelectedProject } = useProjectsStore(); + const { projects, fetchAndSelectProject, setSelectedProject } = useProjectsStore(); const navigate = useNavigate(); useEffect(() => { - fetchProjects(config); - }, [fetchProjects, config]); + fetchAndSelectProject(config); + }, [fetchAndSelectProject, config]); return (
@@ -38,7 +38,7 @@ const Root = () => { ); - //TODO: Handle these cases (probs toast and navigate away?) + //TODO: Handle these cases (probs toast and navigate away?) case 'hasError': return
Error encountered
; // Render the error case 'hasDataWithError': diff --git a/frontend/src/utils.ts b/frontend/src/utils.ts new file mode 100644 index 0000000..640fdf0 --- /dev/null +++ b/frontend/src/utils.ts @@ -0,0 +1,9 @@ +/** + * Utility function to get the first letter of a string. + * + * @param str - The input string. + * @returns The first letter of the string, or '' if the string is null or empty. + */ +export const getFirstLetter = (str: string | null | undefined): string => { + return str && str.length > 0 ? str.charAt(0) : ''; +}