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) : '';
+}