From 0ec9e2163b36d4e2646a8a384876def49da6fcf3 Mon Sep 17 00:00:00 2001 From: Aiga115 Date: Wed, 23 Apr 2025 16:08:14 +0200 Subject: [PATCH 1/5] ILEX-91-B connect organizations on dashboard --- .../Dashboard/Organizations/index.jsx | 102 +++++++++++++++++- src/components/common/OrganizationsList.jsx | 4 +- 2 files changed, 100 insertions(+), 6 deletions(-) diff --git a/src/components/Dashboard/Organizations/index.jsx b/src/components/Dashboard/Organizations/index.jsx index 87e65e1e..477e5bd6 100644 --- a/src/components/Dashboard/Organizations/index.jsx +++ b/src/components/Dashboard/Organizations/index.jsx @@ -1,15 +1,89 @@ -import {Box, Button, ButtonGroup, Divider, Typography} from "@mui/material"; +import {Box, Button, ButtonGroup, Divider, Typography, CircularProgress, Link} from "@mui/material"; import { useState } from "react"; import { vars } from "../../../theme/variables"; import { ListIcon, TableChartIcon } from "../../../Icons"; import AddOutlinedIcon from "@mui/icons-material/AddOutlined"; -import organizationss from "../../../static/Organizations.json"; import OrganizationsList from "../../common/OrganizationsList"; import CustomViewButton from "../../common/CustomViewButton"; +import { createNewOrganization } from "../../../api/endpoints/apiService"; +import BasicDialog from "../../common/BasicDialog"; + +const { gray600, gray200, brand700, brand800 } = vars; + +const linkStyles = { + color: brand700, + fontWeight: 600, + textDecoration: "none", + "&:hover": { + color: brand800 + } +} -const { gray600, gray200 } = vars; const Organizations = () => { const [listView, setListView] = useState('list'); + const [organizations, setOrganizations] = useState([]); + const [loading, setLoading] = useState(false); + const [message, setMessage] = useState(); + const [open, setOpen] = useState(false); + + // TODO: change this to be dynamic when we get the response from api call + const groupname = "aigul" + + const handleOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + }; + + const fetchOrganizations = async() => { + setLoading(true); + + try { + const response = await getOrganizations(groupname) + if(response.length > 0){ + setOrganizations(response) + } + } catch (err) { + console.error('An unknown error occurred: ', err); + } finally { + setLoading(false); + } + } + + const createOrganization = async (event) => { + event.preventDefault(); + setLoading(true); + + try { + // eslint-disable-next-line no-unused-vars + const response = await createNewOrganization({ group: groupname, data: "a test" }) + + } catch (err) { + console.error('An unknown error occurred: ', err); + + console.log("error.res.status: ", err.response.status) + if(err.response.status === 501) { + setMessage(err.response.data) + } + } finally { + setLoading(false); + } + + handleOpen() + } + + useEffect( () => { + setLoading(true) + fetchOrganizations(); + }, []); + + if (loading) { + return + + + } return ( { /> - - + + {message && ( + + + {message?.split(/(\S+@\S+\.\S+)/).map((part, i) => + part.match(/\S+@\S+\.\S+/) ? {part} : part + )} + + + )} ); }; diff --git a/src/components/common/OrganizationsList.jsx b/src/components/common/OrganizationsList.jsx index 0da0e8b3..7119f896 100644 --- a/src/components/common/OrganizationsList.jsx +++ b/src/components/common/OrganizationsList.jsx @@ -73,7 +73,7 @@ const OrganizationsList = ({organizations, viewJoinButton = true}) => { } } }}> - {organizations.length > 0 && ( + {organizations.length > 0 ? ( organizations?.map((organization, index) => ( navigate(`/organizations/${organization.name}`)}> @@ -104,6 +104,8 @@ const OrganizationsList = ({organizations, viewJoinButton = true}) => { } secondary={organization.description} /> )) + ) : ( + There are no organizations )} ); From 29e112735b7dd8594c1c1ce7d95c49799769a94b Mon Sep 17 00:00:00 2001 From: Aiga115 Date: Wed, 23 Apr 2025 16:09:18 +0200 Subject: [PATCH 2/5] ILEX-91-B add useEffect hook --- src/components/Dashboard/Organizations/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Dashboard/Organizations/index.jsx b/src/components/Dashboard/Organizations/index.jsx index 477e5bd6..3074d2b4 100644 --- a/src/components/Dashboard/Organizations/index.jsx +++ b/src/components/Dashboard/Organizations/index.jsx @@ -1,5 +1,5 @@ import {Box, Button, ButtonGroup, Divider, Typography, CircularProgress, Link} from "@mui/material"; -import { useState } from "react"; +import { useState, useEffect } from "react"; import { vars } from "../../../theme/variables"; import { ListIcon, TableChartIcon } from "../../../Icons"; import AddOutlinedIcon from "@mui/icons-material/AddOutlined"; From fbd19277c20ff57d9848ee433debfcc885e43ee7 Mon Sep 17 00:00:00 2001 From: Aiga115 Date: Wed, 23 Apr 2025 16:42:02 +0200 Subject: [PATCH 3/5] ILEX-91-B small fix --- src/components/Dashboard/Organizations/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Dashboard/Organizations/index.jsx b/src/components/Dashboard/Organizations/index.jsx index 3074d2b4..b2a53c6d 100644 --- a/src/components/Dashboard/Organizations/index.jsx +++ b/src/components/Dashboard/Organizations/index.jsx @@ -5,7 +5,7 @@ import { ListIcon, TableChartIcon } from "../../../Icons"; import AddOutlinedIcon from "@mui/icons-material/AddOutlined"; import OrganizationsList from "../../common/OrganizationsList"; import CustomViewButton from "../../common/CustomViewButton"; -import { createNewOrganization } from "../../../api/endpoints/apiService"; +import { createNewOrganization, getOrganizations } from "../../../api/endpoints/apiService"; import BasicDialog from "../../common/BasicDialog"; const { gray600, gray200, brand700, brand800 } = vars; From d042b037490fb97c7cdbe2c6746377699b63ad85 Mon Sep 17 00:00:00 2001 From: Aiga115 Date: Wed, 23 Apr 2025 23:50:33 +0200 Subject: [PATCH 4/5] ILEX-91-B create hook to handle organization state --- .../Dashboard/Organizations/index.jsx | 97 ++++--------------- src/components/common/MessageDialog.jsx | 35 +++++++ src/components/common/OrganizationsList.jsx | 1 + src/components/organizations/index.jsx | 96 ++++-------------- src/helpers/useOrganizations.ts | 56 +++++++++++ 5 files changed, 131 insertions(+), 154 deletions(-) create mode 100644 src/components/common/MessageDialog.jsx create mode 100644 src/helpers/useOrganizations.ts diff --git a/src/components/Dashboard/Organizations/index.jsx b/src/components/Dashboard/Organizations/index.jsx index b2a53c6d..6490090d 100644 --- a/src/components/Dashboard/Organizations/index.jsx +++ b/src/components/Dashboard/Organizations/index.jsx @@ -1,35 +1,35 @@ -import {Box, Button, ButtonGroup, Divider, Typography, CircularProgress, Link} from "@mui/material"; -import { useState, useEffect } from "react"; +import { Box, Button, ButtonGroup, Divider, Typography, CircularProgress } from "@mui/material"; +import { useState } from "react"; +import { useOrganizations } from "../../../helpers/useOrganizations"; import { vars } from "../../../theme/variables"; import { ListIcon, TableChartIcon } from "../../../Icons"; import AddOutlinedIcon from "@mui/icons-material/AddOutlined"; import OrganizationsList from "../../common/OrganizationsList"; import CustomViewButton from "../../common/CustomViewButton"; -import { createNewOrganization, getOrganizations } from "../../../api/endpoints/apiService"; -import BasicDialog from "../../common/BasicDialog"; +import MessageDialog from "../../common/MessageDialog"; -const { gray600, gray200, brand700, brand800 } = vars; +const { gray600, gray200 } = vars; -const linkStyles = { - color: brand700, - fontWeight: 600, - textDecoration: "none", - "&:hover": { - color: brand800 - } -} const Organizations = () => { - const [listView, setListView] = useState('list'); - const [organizations, setOrganizations] = useState([]); - const [loading, setLoading] = useState(false); - const [message, setMessage] = useState(); const [open, setOpen] = useState(false); // TODO: change this to be dynamic when we get the response from api call const groupname = "aigul" - const handleOpen = () => { + const { + listView, + setListView, + organizations, + loading, + message, + createOrganization + } = useOrganizations(groupname); + + const handleCreateOrganization = async (e) => { + e.preventDefault(); + // eslint-disable-next-line no-unused-vars + const success = await createOrganization(); setOpen(true); }; @@ -37,48 +37,6 @@ const Organizations = () => { setOpen(false); }; - const fetchOrganizations = async() => { - setLoading(true); - - try { - const response = await getOrganizations(groupname) - if(response.length > 0){ - setOrganizations(response) - } - } catch (err) { - console.error('An unknown error occurred: ', err); - } finally { - setLoading(false); - } - } - - const createOrganization = async (event) => { - event.preventDefault(); - setLoading(true); - - try { - // eslint-disable-next-line no-unused-vars - const response = await createNewOrganization({ group: groupname, data: "a test" }) - - } catch (err) { - console.error('An unknown error occurred: ', err); - - console.log("error.res.status: ", err.response.status) - if(err.response.status === 501) { - setMessage(err.response.data) - } - } finally { - setLoading(false); - } - - handleOpen() - } - - useEffect( () => { - setLoading(true) - fetchOrganizations(); - }, []); - if (loading) { return @@ -116,7 +74,7 @@ const Organizations = () => { /> - + {message && ( - - - {message?.split(/(\S+@\S+\.\S+)/).map((part, i) => - part.match(/\S+@\S+\.\S+/) ? {part} : part - )} - - + )} ); diff --git a/src/helpers/useOrganizations.ts b/src/helpers/useOrganizations.ts new file mode 100644 index 00000000..05e69f04 --- /dev/null +++ b/src/helpers/useOrganizations.ts @@ -0,0 +1,56 @@ +import { useState, useEffect } from 'react'; +import { getOrganizations, createNewOrganization } from '../api/endpoints/apiService'; + +export const useOrganizations = (groupname: string) => { + const [listView, setListView] = useState('list'); + const [organizations, setOrganizations] = useState([]); + const [loading, setLoading] = useState(false); + const [message, setMessage] = useState(); + + const fetchOrganizations = async () => { + setLoading(true); + + try { + const response = await getOrganizations(groupname); + if (response.length > 0) { + setOrganizations(response[0]); + } + } catch (err) { + console.error('An unknown error occurred: ', err); + } finally { + setLoading(false); + } + }; + + const createOrganization = async (event) => { + if (event) event.preventDefault(); + setLoading(true); + + try { + await createNewOrganization({ group: groupname, data: "a test" }); + } catch (err) { + console.error('An unknown error occurred: ', err); + if (err.response?.status === 501) { + setMessage(err.response.data); + } + } finally { + setLoading(false); + } + }; + + useEffect(() => { + setLoading(true); + fetchOrganizations(); + }, []); + + return { + listView, + setListView, + organizations, + loading, + message, + open, + createOrganization, + fetchOrganizations + }; +}; \ No newline at end of file From af8def0da9e1d10795b888ce9cc5505d5bbe19f5 Mon Sep 17 00:00:00 2001 From: Aiga115 Date: Thu, 24 Apr 2025 12:12:44 +0200 Subject: [PATCH 5/5] ILEX-91-B fix linting --- src/components/common/MessageDialog.jsx | 8 ++++++++ src/components/organizations/index.jsx | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/common/MessageDialog.jsx b/src/components/common/MessageDialog.jsx index bd672ded..465c40f6 100644 --- a/src/components/common/MessageDialog.jsx +++ b/src/components/common/MessageDialog.jsx @@ -1,3 +1,4 @@ +import PropTypes from "prop-types"; import { Typography, Link } from '@mui/material'; import BasicDialog from './BasicDialog'; import { vars } from '../../theme/variables'; @@ -32,4 +33,11 @@ const MessageDialog = ({ title, open, handleClose, message }) => ( ) +MessageDialog.propTypes = { + title: PropTypes.string, + open: PropTypes.bool, + handleClose: PropTypes.func, + message: PropTypes.string +}; + export default MessageDialog; \ No newline at end of file diff --git a/src/components/organizations/index.jsx b/src/components/organizations/index.jsx index 8f454616..514688bb 100644 --- a/src/components/organizations/index.jsx +++ b/src/components/organizations/index.jsx @@ -1,6 +1,6 @@ import { useState } from "react"; import OrganizationsList from "../common/OrganizationsList"; -import { Box, Typography, CircularProgress, Stack, Button, Link } from "@mui/material"; +import { Box, Typography, CircularProgress, Stack, Button } from "@mui/material"; import { useOrganizations } from "../../helpers/useOrganizations"; import GroupAddOutlinedIcon from "@mui/icons-material/GroupAddOutlined"; import MessageDialog from "../common/MessageDialog";