From d382138fe4a55f320f190a3a0c80d2c93ad5a827 Mon Sep 17 00:00:00 2001 From: Yonas Date: Thu, 26 Oct 2023 14:01:54 +0300 Subject: [PATCH 01/24] delete old graphql button --- .../webapp/src/Components/Button.test.tsx | 82 ------------------- applications/webapp/src/Components/Button.tsx | 64 --------------- 2 files changed, 146 deletions(-) delete mode 100644 applications/webapp/src/Components/Button.test.tsx delete mode 100644 applications/webapp/src/Components/Button.tsx diff --git a/applications/webapp/src/Components/Button.test.tsx b/applications/webapp/src/Components/Button.test.tsx deleted file mode 100644 index 79c526a2..00000000 --- a/applications/webapp/src/Components/Button.test.tsx +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Humanitech Supply Trail - * - * Copyright (c) Humanitech, Peter Rogov and Contributors - * - * Website: https://humanitech.net - * Repository: https://github.com/humanitech-net/supply-trail - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import React from "react"; -import { - cleanup, - render, - fireEvent, - waitFor, - screen, -} from "@testing-library/react"; -import GraphQlButton, { Connection } from "./Button"; -import { MockedProvider } from "@apollo/client/testing"; -import { GraphQLError } from "graphql"; - -const mockData = { - findAll: { - id: 1, - firstName: "Test", - }, -}; - -const successMock = { - request: { - query: Connection, - }, - result: { - data: mockData, - }, -}; - -const errorMock = { - request: { - query: Connection, - }, - error: new GraphQLError("the fetch was unsuccessful"), -}; - -describe("GraphQlButton", () => { - afterEach(() => { - cleanup(); - }); - - it("should render data when fetched successfully", async () => { - render( - - - , - ); - - fireEvent.click(screen.getByText("Click Me")); - - await waitFor(() => { - expect(screen.getByText("ID: 1")).toBeInTheDocument; - expect(screen.getByText("First Name: Test")).toBeInTheDocument; - }); - }); - - it("should render error message when fetch fails", async () => { - render( - - - , - ); - - fireEvent.click(screen.getByText("Click Me")); - - await waitFor(() => { - expect(screen.getByText("Error: the fetch was unsuccessful")) - .toBeInTheDocument; - }); - }); -}); diff --git a/applications/webapp/src/Components/Button.tsx b/applications/webapp/src/Components/Button.tsx deleted file mode 100644 index 35b09412..00000000 --- a/applications/webapp/src/Components/Button.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Humanitech Supply Trail - * - * Copyright (c) Humanitech, Peter Rogov and Contributors - * - * Website: https://humanitech.net - * Repository: https://github.com/humanitech-net/supply-trail - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import React, { useState } from "react"; -import { useQuery, gql } from "@apollo/client"; -import { Button } from "@mui/material"; - -export const Connection = gql` - query { - findAll { - id - firstName - } - } -`; - -const GraphQlButton: React.FC = () => { - const [isDataFetched, setIsDataFetched] = useState(false); - - const { error, data, refetch } = useQuery(Connection, { - skip: !isDataFetched, - }); - - const handleButtonClick = () => { - setIsDataFetched(true); - refetch(); - }; - - if (error) { - return ( -
- -
Error: {error.message}
-
- ); - } - - return ( -
- - {isDataFetched && ( -
-
    ID: {data?.findAll?.id}
-
    First Name: {data?.findAll?.firstName}
-
- )} -
- ); -}; - -export default GraphQlButton; From 0224a7f477d63bd8e45aef3b430d4fef47f2107b Mon Sep 17 00:00:00 2001 From: Yonas Date: Thu, 26 Oct 2023 14:56:43 +0300 Subject: [PATCH 02/24] refactor leftDrawer --- .../webapp/src/Components/leftDrawer.tsx | 106 ------------------ .../LeftDrawer/Components/drawerHeader.tsx | 34 ++++++ .../Home/LeftDrawer/Components/drawerMenu.tsx | 29 +++++ .../src/Pages/Home/LeftDrawer/leftDrawer.tsx | 46 ++++++++ .../Home/LeftDrawer/tests}/drawer.test.tsx | 0 .../Pages/Home/LeftDrawer/util/constants.ts | 9 ++ .../src/Pages/Home/LeftDrawer/util/style.ts | 13 +++ applications/webapp/src/Pages/Home/home.tsx | 2 +- 8 files changed, 132 insertions(+), 107 deletions(-) delete mode 100644 applications/webapp/src/Components/leftDrawer.tsx create mode 100644 applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerHeader.tsx create mode 100644 applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerMenu.tsx create mode 100644 applications/webapp/src/Pages/Home/LeftDrawer/leftDrawer.tsx rename applications/webapp/src/{Components/test => Pages/Home/LeftDrawer/tests}/drawer.test.tsx (100%) create mode 100644 applications/webapp/src/Pages/Home/LeftDrawer/util/constants.ts create mode 100644 applications/webapp/src/Pages/Home/LeftDrawer/util/style.ts diff --git a/applications/webapp/src/Components/leftDrawer.tsx b/applications/webapp/src/Components/leftDrawer.tsx deleted file mode 100644 index f5890d1d..00000000 --- a/applications/webapp/src/Components/leftDrawer.tsx +++ /dev/null @@ -1,106 +0,0 @@ -/** - * Humanitech Supply Trail - * - * Copyright (c) Humanitech, Peter Rogov and Contributors - * - * Website: https://humanitech.net - * Repository: https://github.com/humanitech-net/supply-trail - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import React from "react"; -import { styled, useTheme } from "@mui/material/styles"; -import Drawer from "@mui/material/Drawer"; -import List from "@mui/material/List"; -import IconButton from "@mui/material/IconButton"; -import ListItem from "@mui/material/ListItem"; -import ListItemButton from "@mui/material/ListItemButton"; -import ListItemText from "@mui/material/ListItemText"; -import MenuIcon from "@mui/icons-material/Menu"; -import useMediaQuery from "@mui/material/useMediaQuery"; - -interface DrawerProps { - open: boolean; - closeDrawer: () => void; -} - -export default function LeftDrawer({ - open, - closeDrawer, -}: Readonly) { - const drawerWidth = 240; - const theme = useTheme(); - const isDesktop = useMediaQuery(theme.breakpoints.up("md")); - const menu = [ - "Supply", - "Tracking", - "Inventory", - "Logistics", - "Schools", - "Analytics", - "Contact List", - ]; - - const DrawerHeader = styled("div")(({ theme }) => ({ - display: "flex", - alignItems: "center", - padding: theme.spacing(0, 1), - ...theme.mixins.toolbar, - justifyContent: "flex-start", - paddingLeft: 22, - backgroundColor: "#011C27", - })); - - return ( - - - - - - - - {menu.map((text) => ( - - - - - - ))} - - - ); -} diff --git a/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerHeader.tsx b/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerHeader.tsx new file mode 100644 index 00000000..1f62b9f0 --- /dev/null +++ b/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerHeader.tsx @@ -0,0 +1,34 @@ +import React from "react"; +import { IconButton, styled } from "@mui/material"; + +import MenuIcon from "@mui/icons-material/Menu"; + +interface DrawerHeaderProps { + closeDrawer: () => void; +} + +export default function DrawerHeader({ closeDrawer }: DrawerHeaderProps) { + const DrawerHeader = styled("div")(({ theme }) => ({ + display: "flex", + alignItems: "center", + padding: theme.spacing(0, 1), + ...theme.mixins.toolbar, + justifyContent: "flex-start", + paddingLeft: 22, + backgroundColor: "#011C27", + })); + + return ( + + + + + + ); +} diff --git a/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerMenu.tsx b/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerMenu.tsx new file mode 100644 index 00000000..8a3dc1c8 --- /dev/null +++ b/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerMenu.tsx @@ -0,0 +1,29 @@ +import React from "react"; +import { List, ListItem, ListItemButton, ListItemText } from "@mui/material"; +import { drawerMenu } from "../util/constants"; + +export default function DrawerMenu() { + return ( + + {drawerMenu.map((text) => ( + + + + + + ))} + + ); +} diff --git a/applications/webapp/src/Pages/Home/LeftDrawer/leftDrawer.tsx b/applications/webapp/src/Pages/Home/LeftDrawer/leftDrawer.tsx new file mode 100644 index 00000000..c19be4ab --- /dev/null +++ b/applications/webapp/src/Pages/Home/LeftDrawer/leftDrawer.tsx @@ -0,0 +1,46 @@ +/** + * Humanitech Supply Trail + * + * Copyright (c) Humanitech, Peter Rogov and Contributors + * + * Website: https://humanitech.net + * Repository: https://github.com/humanitech-net/supply-trail + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from "react"; +import { useTheme } from "@mui/material/styles"; +import Drawer from "@mui/material/Drawer"; +import useMediaQuery from "@mui/material/useMediaQuery"; +import DrawerHeader from "./Components/drawerHeader"; +import DrawerMenu from "./Components/drawerMenu"; +import { styles } from "./util/style"; + +interface DrawerProps { + open: boolean; + closeDrawer: () => void; +} + +export default function LeftDrawer({ + open, + closeDrawer, +}: Readonly) { + const theme = useTheme(); + const style = styles(); + + const isDesktop = useMediaQuery(theme.breakpoints.up("md")); + + return ( + + + + + ); +} diff --git a/applications/webapp/src/Components/test/drawer.test.tsx b/applications/webapp/src/Pages/Home/LeftDrawer/tests/drawer.test.tsx similarity index 100% rename from applications/webapp/src/Components/test/drawer.test.tsx rename to applications/webapp/src/Pages/Home/LeftDrawer/tests/drawer.test.tsx diff --git a/applications/webapp/src/Pages/Home/LeftDrawer/util/constants.ts b/applications/webapp/src/Pages/Home/LeftDrawer/util/constants.ts new file mode 100644 index 00000000..54763e6c --- /dev/null +++ b/applications/webapp/src/Pages/Home/LeftDrawer/util/constants.ts @@ -0,0 +1,9 @@ +export const drawerMenu = [ + "Supply", + "Tracking", + "Inventory", + "Logistics", + "Schools", + "Analytics", + "Contact List", +]; diff --git a/applications/webapp/src/Pages/Home/LeftDrawer/util/style.ts b/applications/webapp/src/Pages/Home/LeftDrawer/util/style.ts new file mode 100644 index 00000000..694a692e --- /dev/null +++ b/applications/webapp/src/Pages/Home/LeftDrawer/util/style.ts @@ -0,0 +1,13 @@ +// import { Theme } from "@emotion/react"; + +export const styles = () => ({ + drawer: { + width: 240, + flexShrink: 0, + "& .MuiDrawer-paper": { + width: 240, + boxSizing: "border-box", + backgroundColor: "#011C27", + }, + }, +}); diff --git a/applications/webapp/src/Pages/Home/home.tsx b/applications/webapp/src/Pages/Home/home.tsx index a248ba50..4ab65205 100644 --- a/applications/webapp/src/Pages/Home/home.tsx +++ b/applications/webapp/src/Pages/Home/home.tsx @@ -14,7 +14,7 @@ import React from "react"; import Box from "@mui/material/Box"; import CssBaseline from "@mui/material/CssBaseline"; import NavBar from "../../Components/navbar"; -import LeftDrawer from "../../Components/leftDrawer"; +import LeftDrawer from "./LeftDrawer/leftDrawer"; import MainContent from "../../Components/mainContent"; export default function Home() { From ecdafe2969b59a4de0d59dc6eea86dd58270daa2 Mon Sep 17 00:00:00 2001 From: Yonas Date: Thu, 26 Oct 2023 15:59:09 +0300 Subject: [PATCH 03/24] add drawer context provider --- .../Home/ContextProvider/drawerProvider.tsx | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 applications/webapp/src/Pages/Home/ContextProvider/drawerProvider.tsx diff --git a/applications/webapp/src/Pages/Home/ContextProvider/drawerProvider.tsx b/applications/webapp/src/Pages/Home/ContextProvider/drawerProvider.tsx new file mode 100644 index 00000000..37221fc7 --- /dev/null +++ b/applications/webapp/src/Pages/Home/ContextProvider/drawerProvider.tsx @@ -0,0 +1,37 @@ +/** + * Humanitech Supply Trail + * + * Copyright (c) Humanitech, Peter Rogov and Contributors + * + * Website: https://humanitech.net + * Repository: https://github.com/humanitech-net/supply-trail + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, { ReactNode, createContext, useState } from "react"; + +interface DrawerContextProps { + open: boolean; + setOpen: (open: boolean) => void; +} + +interface DrawerProviderProps { + children: ReactNode; +} + +export const DrawerContext = createContext({ + open: false, + setOpen: () => {}, +}); + +export const DrawerProvider: React.FC = ({ children }) => { + const [open, setOpen] = useState(false); + + return ( + + {children} + + ); +}; From fca4b07dbc43f0b77f98c706e28dec71ff1755ef Mon Sep 17 00:00:00 2001 From: Yonas Date: Thu, 26 Oct 2023 16:02:48 +0300 Subject: [PATCH 04/24] update how props is passed to children --- .../webapp/src/Components/mainContent.tsx | 13 +++++----- applications/webapp/src/Components/navbar.tsx | 14 +++++------ .../LeftDrawer/Components/drawerHeader.tsx | 13 ++++++---- .../src/Pages/Home/LeftDrawer/leftDrawer.tsx | 18 ++++++------- applications/webapp/src/Pages/Home/home.tsx | 25 +++++++------------ 5 files changed, 37 insertions(+), 46 deletions(-) diff --git a/applications/webapp/src/Components/mainContent.tsx b/applications/webapp/src/Components/mainContent.tsx index 1dd052ee..a74c803b 100644 --- a/applications/webapp/src/Components/mainContent.tsx +++ b/applications/webapp/src/Components/mainContent.tsx @@ -10,22 +10,21 @@ * LICENSE file in the root directory of this source tree. */ -import React from "react"; +import React, { useContext } from "react"; import { styled, useTheme } from "@mui/material/styles"; import useMediaQuery from "@mui/material/useMediaQuery"; import { Routes, Route } from "react-router-dom"; import UserPage from "../Pages/User/userPage"; +import { DrawerContext } from "src/Pages/Home/ContextProvider/drawerProvider"; -interface HandleDrawer { - open: boolean; -} - -export default function MainContent({ open }: Readonly) { +export default function MainContent() { const drawerWidth = 240; const theme = useTheme(); const isDesktop = useMediaQuery(theme.breakpoints.up("md")); + const { open } = useContext(DrawerContext); + const Main = styled("main", { shouldForwardProp: (prop) => prop !== "open", })<{ @@ -49,7 +48,7 @@ export default function MainContent({ open }: Readonly) { }), })); return ( -
+
} /> diff --git a/applications/webapp/src/Components/navbar.tsx b/applications/webapp/src/Components/navbar.tsx index 14f60f97..57642a63 100644 --- a/applications/webapp/src/Components/navbar.tsx +++ b/applications/webapp/src/Components/navbar.tsx @@ -10,7 +10,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from "react"; +import React, { useContext } from "react"; import { Link } from "react-router-dom"; import Box from "@mui/material/Box"; import { styled } from "@mui/material/styles"; @@ -22,14 +22,10 @@ import MenuIcon from "@mui/icons-material/Menu"; import AccountCircle from "@mui/icons-material/AccountCircle"; import Brightness4Icon from "@mui/icons-material/Brightness4"; import NotificationsIcon from "@mui/icons-material/Notifications"; +import { DrawerContext } from "src/Pages/Home/ContextProvider/drawerProvider"; const drawerWidth = 240; -interface HandleDrawer { - open: boolean; - openDrawer: () => void; -} - interface AppBarProps extends MuiAppBarProps { open?: boolean; } @@ -51,7 +47,11 @@ const AppBar = styled(MuiAppBar, { }), })); -export default function NavBar({ open, openDrawer }: Readonly) { +export default function NavBar() { + const { open, setOpen } = useContext(DrawerContext); + const openDrawer = () => { + setOpen(true); + }; return ( void; -} +export default function DrawerHeader() { + const { setOpen } = useContext(DrawerContext); + + const closeDrawer = () => { + setOpen(false); + }; -export default function DrawerHeader({ closeDrawer }: DrawerHeaderProps) { const DrawerHeader = styled("div")(({ theme }) => ({ display: "flex", alignItems: "center", diff --git a/applications/webapp/src/Pages/Home/LeftDrawer/leftDrawer.tsx b/applications/webapp/src/Pages/Home/LeftDrawer/leftDrawer.tsx index c19be4ab..6a0d92f7 100644 --- a/applications/webapp/src/Pages/Home/LeftDrawer/leftDrawer.tsx +++ b/applications/webapp/src/Pages/Home/LeftDrawer/leftDrawer.tsx @@ -10,28 +10,24 @@ * LICENSE file in the root directory of this source tree. */ -import React from "react"; +import React, { useContext } from "react"; import { useTheme } from "@mui/material/styles"; import Drawer from "@mui/material/Drawer"; import useMediaQuery from "@mui/material/useMediaQuery"; import DrawerHeader from "./Components/drawerHeader"; import DrawerMenu from "./Components/drawerMenu"; import { styles } from "./util/style"; +import { DrawerContext } from "../ContextProvider/drawerProvider"; +// import { DrawerContext } from "./Components/DrawerContextProvider"; -interface DrawerProps { - open: boolean; - closeDrawer: () => void; -} - -export default function LeftDrawer({ - open, - closeDrawer, -}: Readonly) { +export default function LeftDrawer() { const theme = useTheme(); const style = styles(); const isDesktop = useMediaQuery(theme.breakpoints.up("md")); + const { open } = useContext(DrawerContext); + return ( - + ); diff --git a/applications/webapp/src/Pages/Home/home.tsx b/applications/webapp/src/Pages/Home/home.tsx index 4ab65205..53daf96b 100644 --- a/applications/webapp/src/Pages/Home/home.tsx +++ b/applications/webapp/src/Pages/Home/home.tsx @@ -16,24 +16,17 @@ import CssBaseline from "@mui/material/CssBaseline"; import NavBar from "../../Components/navbar"; import LeftDrawer from "./LeftDrawer/leftDrawer"; import MainContent from "../../Components/mainContent"; +import { DrawerProvider } from "./ContextProvider/drawerProvider"; export default function Home() { - const [open, setOpen] = React.useState(false); - - function openDrawer() { - setOpen(true); - } - - function closeDrawer() { - setOpen(false); - } - return ( - - - - - - + + + + + + + + ); } From 650173dcb8a5b33a758d41384386b0db45eb997b Mon Sep 17 00:00:00 2001 From: Yonas Date: Thu, 26 Oct 2023 16:05:25 +0300 Subject: [PATCH 05/24] update unit test --- applications/webapp/src/Components/test/mainContent.test.tsx | 2 +- applications/webapp/src/Components/test/navbar.test.tsx | 4 +--- .../webapp/src/Pages/Home/LeftDrawer/tests/drawer.test.tsx | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/applications/webapp/src/Components/test/mainContent.test.tsx b/applications/webapp/src/Components/test/mainContent.test.tsx index 74d0d0e8..10b81a9d 100644 --- a/applications/webapp/src/Components/test/mainContent.test.tsx +++ b/applications/webapp/src/Components/test/mainContent.test.tsx @@ -19,7 +19,7 @@ describe("MainContent", () => { test("renders MainContent component", () => { render( - + , ); }); diff --git a/applications/webapp/src/Components/test/navbar.test.tsx b/applications/webapp/src/Components/test/navbar.test.tsx index e9a9b91c..ff434e57 100644 --- a/applications/webapp/src/Components/test/navbar.test.tsx +++ b/applications/webapp/src/Components/test/navbar.test.tsx @@ -17,11 +17,9 @@ import { MemoryRouter } from "react-router-dom"; describe("NavBar", () => { test("renders NavBar component", () => { - const openDrawerMock = jest.fn(); - render( - + , ); }); diff --git a/applications/webapp/src/Pages/Home/LeftDrawer/tests/drawer.test.tsx b/applications/webapp/src/Pages/Home/LeftDrawer/tests/drawer.test.tsx index b57d1cef..baee6e6c 100644 --- a/applications/webapp/src/Pages/Home/LeftDrawer/tests/drawer.test.tsx +++ b/applications/webapp/src/Pages/Home/LeftDrawer/tests/drawer.test.tsx @@ -16,7 +16,6 @@ import LeftDrawer from "../leftDrawer"; describe("LeftDrawer", () => { test("renders LeftDrawer component", () => { - const closeDrawerMock = jest.fn(); - render(); + render(); }); }); From d79fb36d217c29826db00e03efc3238b59b46824 Mon Sep 17 00:00:00 2001 From: Yonas Date: Thu, 26 Oct 2023 16:28:07 +0300 Subject: [PATCH 06/24] refactor main content --- .../Home/MainContent}/mainContent.tsx | 28 +++++-------------- .../MainContent/tests}/mainContent.test.tsx | 0 2 files changed, 7 insertions(+), 21 deletions(-) rename applications/webapp/src/{Components => Pages/Home/MainContent}/mainContent.tsx (62%) rename applications/webapp/src/{Components/test => Pages/Home/MainContent/tests}/mainContent.test.tsx (100%) diff --git a/applications/webapp/src/Components/mainContent.tsx b/applications/webapp/src/Pages/Home/MainContent/mainContent.tsx similarity index 62% rename from applications/webapp/src/Components/mainContent.tsx rename to applications/webapp/src/Pages/Home/MainContent/mainContent.tsx index a74c803b..7ca35f43 100644 --- a/applications/webapp/src/Components/mainContent.tsx +++ b/applications/webapp/src/Pages/Home/MainContent/mainContent.tsx @@ -11,42 +11,28 @@ */ import React, { useContext } from "react"; -import { styled, useTheme } from "@mui/material/styles"; -import useMediaQuery from "@mui/material/useMediaQuery"; +import { styled } from "@mui/material/styles"; import { Routes, Route } from "react-router-dom"; -import UserPage from "../Pages/User/userPage"; +import UserPage from "../../User/userPage"; import { DrawerContext } from "src/Pages/Home/ContextProvider/drawerProvider"; +import { useMediaQuery, useTheme } from "@mui/material"; export default function MainContent() { - const drawerWidth = 240; + const { open } = useContext(DrawerContext); const theme = useTheme(); const isDesktop = useMediaQuery(theme.breakpoints.up("md")); - const { open } = useContext(DrawerContext); - - const Main = styled("main", { - shouldForwardProp: (prop) => prop !== "open", - })<{ - open?: boolean; - }>(({ theme }) => ({ + const Main = styled("main")(({ theme }) => ({ + marginLeft: open && isDesktop ? 240 : 0, marginTop: 80, flexGrow: 1, transition: theme.transitions.create("margin", { easing: theme.transitions.easing.sharp, duration: theme.transitions.duration.leavingScreen, }), - - ...(isDesktop && { - ...(open && { - marginLeft: drawerWidth, - transition: theme.transitions.create("margin", { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.enteringScreen, - }), - }), - }), })); + return (
diff --git a/applications/webapp/src/Components/test/mainContent.test.tsx b/applications/webapp/src/Pages/Home/MainContent/tests/mainContent.test.tsx similarity index 100% rename from applications/webapp/src/Components/test/mainContent.test.tsx rename to applications/webapp/src/Pages/Home/MainContent/tests/mainContent.test.tsx From 130e471183016da407fb61922cbab2fac53ad40d Mon Sep 17 00:00:00 2001 From: Yonas Date: Thu, 26 Oct 2023 16:33:21 +0300 Subject: [PATCH 07/24] refactor footer --- .../webapp/src/{Components => Pages/Home/Footer}/footer.tsx | 0 .../test => Pages/Home/Footer/tests}/footer.test.tsx | 0 applications/webapp/src/Pages/Home/{test => }/home.test.tsx | 2 +- applications/webapp/src/Pages/Home/home.tsx | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) rename applications/webapp/src/{Components => Pages/Home/Footer}/footer.tsx (100%) rename applications/webapp/src/{Components/test => Pages/Home/Footer/tests}/footer.test.tsx (100%) rename applications/webapp/src/Pages/Home/{test => }/home.test.tsx (98%) diff --git a/applications/webapp/src/Components/footer.tsx b/applications/webapp/src/Pages/Home/Footer/footer.tsx similarity index 100% rename from applications/webapp/src/Components/footer.tsx rename to applications/webapp/src/Pages/Home/Footer/footer.tsx diff --git a/applications/webapp/src/Components/test/footer.test.tsx b/applications/webapp/src/Pages/Home/Footer/tests/footer.test.tsx similarity index 100% rename from applications/webapp/src/Components/test/footer.test.tsx rename to applications/webapp/src/Pages/Home/Footer/tests/footer.test.tsx diff --git a/applications/webapp/src/Pages/Home/test/home.test.tsx b/applications/webapp/src/Pages/Home/home.test.tsx similarity index 98% rename from applications/webapp/src/Pages/Home/test/home.test.tsx rename to applications/webapp/src/Pages/Home/home.test.tsx index 3d2fa8c7..85e2589f 100644 --- a/applications/webapp/src/Pages/Home/test/home.test.tsx +++ b/applications/webapp/src/Pages/Home/home.test.tsx @@ -13,7 +13,7 @@ import React from "react"; import { render, fireEvent } from "@testing-library/react"; import { MemoryRouter } from "react-router-dom"; -import Home from "../home"; +import Home from "./home"; describe("Home", () => { test("renders navbar", () => { diff --git a/applications/webapp/src/Pages/Home/home.tsx b/applications/webapp/src/Pages/Home/home.tsx index 53daf96b..fc0251f3 100644 --- a/applications/webapp/src/Pages/Home/home.tsx +++ b/applications/webapp/src/Pages/Home/home.tsx @@ -15,7 +15,7 @@ import Box from "@mui/material/Box"; import CssBaseline from "@mui/material/CssBaseline"; import NavBar from "../../Components/navbar"; import LeftDrawer from "./LeftDrawer/leftDrawer"; -import MainContent from "../../Components/mainContent"; +import MainContent from "./MainContent/mainContent"; import { DrawerProvider } from "./ContextProvider/drawerProvider"; export default function Home() { From 04ce5ad9ddc0e2b203495635441824bc4f8d51df Mon Sep 17 00:00:00 2001 From: Yonas Date: Thu, 26 Oct 2023 16:38:51 +0300 Subject: [PATCH 08/24] change folder path of navbar --- .../webapp/src/{Components => Pages/Home/NavBar}/navbar.tsx | 0 .../test => Pages/Home/NavBar/tests}/navbar.test.tsx | 0 applications/webapp/src/Pages/Home/home.tsx | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) rename applications/webapp/src/{Components => Pages/Home/NavBar}/navbar.tsx (100%) rename applications/webapp/src/{Components/test => Pages/Home/NavBar/tests}/navbar.test.tsx (100%) diff --git a/applications/webapp/src/Components/navbar.tsx b/applications/webapp/src/Pages/Home/NavBar/navbar.tsx similarity index 100% rename from applications/webapp/src/Components/navbar.tsx rename to applications/webapp/src/Pages/Home/NavBar/navbar.tsx diff --git a/applications/webapp/src/Components/test/navbar.test.tsx b/applications/webapp/src/Pages/Home/NavBar/tests/navbar.test.tsx similarity index 100% rename from applications/webapp/src/Components/test/navbar.test.tsx rename to applications/webapp/src/Pages/Home/NavBar/tests/navbar.test.tsx diff --git a/applications/webapp/src/Pages/Home/home.tsx b/applications/webapp/src/Pages/Home/home.tsx index fc0251f3..66226b2e 100644 --- a/applications/webapp/src/Pages/Home/home.tsx +++ b/applications/webapp/src/Pages/Home/home.tsx @@ -13,7 +13,7 @@ import React from "react"; import Box from "@mui/material/Box"; import CssBaseline from "@mui/material/CssBaseline"; -import NavBar from "../../Components/navbar"; +import NavBar from "./NavBar/navbar"; import LeftDrawer from "./LeftDrawer/leftDrawer"; import MainContent from "./MainContent/mainContent"; import { DrawerProvider } from "./ContextProvider/drawerProvider"; From b07b47ed0d34c2c89044aad255b86611623f8b7c Mon Sep 17 00:00:00 2001 From: Yonas Date: Tue, 31 Oct 2023 23:11:45 +0300 Subject: [PATCH 09/24] refacor userpage --- .../Pages/User/components/detailHolder.tsx | 109 ++++++++++-------- .../Pages/User/components/profileHolder.tsx | 55 ++++----- .../webapp/src/Pages/User/userPage.tsx | 20 +--- .../webapp/src/Pages/User/util/style.ts | 3 +- 4 files changed, 92 insertions(+), 95 deletions(-) diff --git a/applications/webapp/src/Pages/User/components/detailHolder.tsx b/applications/webapp/src/Pages/User/components/detailHolder.tsx index 662ef89c..6b4a51dc 100644 --- a/applications/webapp/src/Pages/User/components/detailHolder.tsx +++ b/applications/webapp/src/Pages/User/components/detailHolder.tsx @@ -14,7 +14,6 @@ import React, { useState } from "react"; import { Card, CardContent, - FormControl, Grid, useTheme, TextField, @@ -27,10 +26,12 @@ import { EditUserMutation } from "../../../hooks/mutation"; import { useCardContext, useUserContext } from "../context"; import { Link } from "react-router-dom"; import { CHANGE_PASSWORD_URL } from "../util/constants"; +// import useGenericMutation from "src/hooks/useGenericMutation"; export default function DetailHolder() { const theme = useTheme(); const style = styles(theme).detailHolder; + const boxStyle = styles(theme).userPage; const { user } = useUserContext(); const { firstName, lastName, email, address, birthdate, phoneNumber } = user; @@ -48,8 +49,11 @@ export default function DetailHolder() { try { const { data } = await editUser({ variables: { - firstname, - lastname, + userInput: { + username: user.username, + firstName: firstname, + lastName: lastname, + }, }, }); console.log("User:", data.editUser); @@ -72,83 +76,86 @@ export default function DetailHolder() { return setLastname(event.target.value); } + // const mutate = useGenericMutation("EDIT_USER"); + // console.log(mutate); + return ( - - - - - + + + + + - - + - - + - - - + - - - - - - + + + - - + - - - + - - - - - - + + + - - + - + - - {!card.editable && ( - - - - - - + + + + - - )} - - + )} + + + ); } diff --git a/applications/webapp/src/Pages/User/components/profileHolder.tsx b/applications/webapp/src/Pages/User/components/profileHolder.tsx index 44d393a9..87b2e7f2 100644 --- a/applications/webapp/src/Pages/User/components/profileHolder.tsx +++ b/applications/webapp/src/Pages/User/components/profileHolder.tsx @@ -28,6 +28,7 @@ import { useCardContext, useUserContext } from "../context"; export default function ProfileHolder() { const theme = useTheme(); const style = styles(theme).profileholder; + const boxStyle = styles(theme).userPage; const { user } = useUserContext(); const { username, description } = user; @@ -36,32 +37,34 @@ export default function ProfileHolder() { const { editUser } = card; return ( - - - - - - + + + + + + + + + + {username} + + + {description} + + + + - - {username} - - - {description} - - - - - - - - + + + + ); } diff --git a/applications/webapp/src/Pages/User/userPage.tsx b/applications/webapp/src/Pages/User/userPage.tsx index 49f8b56b..a12c40b2 100644 --- a/applications/webapp/src/Pages/User/userPage.tsx +++ b/applications/webapp/src/Pages/User/userPage.tsx @@ -15,32 +15,20 @@ import { Box, useTheme } from "@mui/material"; import ProfileHolder from "./components/profileHolder"; import DetailHolder from "./components/detailHolder"; import Overlay from "./components/overlay"; -import { styles } from "./util/style"; import { UserPageContextProvider } from "./components/ContextProvider/UserPageContextProvider"; import { CardContextProvider } from "./components/ContextProvider/CardContextProvider"; +import { styles } from "./util/style"; export default function UserPage() { const theme = useTheme(); const style = styles(theme).userPage; - return ( - - - - - - - - + + + diff --git a/applications/webapp/src/Pages/User/util/style.ts b/applications/webapp/src/Pages/User/util/style.ts index 30e146cf..b4f8e995 100644 --- a/applications/webapp/src/Pages/User/util/style.ts +++ b/applications/webapp/src/Pages/User/util/style.ts @@ -69,12 +69,11 @@ export const styles = (theme: Theme) => ({ userPage: { userPageContainer: { display: "flex", - flexDirection: ["column", "column", "row"], + flexDirection: { xs: "column", md: "row" }, margin: "0 20px 0 20px", }, profilePageHolder: { display: "grid", - gridTemplateRows: ["auto", "auto", "repeat(2, 0.2fr)"], gap: [minGap, minGap, maxGap], width: ["100%", "100%", "30%"], margin: ["0 0 20px", "0 0 20px", "0 20px 0 0"], From 5c4b2b99d936eb14912eea24232d00083d2d2550 Mon Sep 17 00:00:00 2001 From: Yonas Date: Wed, 1 Nov 2023 12:11:26 +0300 Subject: [PATCH 10/24] update types --- applications/webapp/src/hooks/types.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/applications/webapp/src/hooks/types.ts b/applications/webapp/src/hooks/types.ts index ed4f7754..91194e5a 100644 --- a/applications/webapp/src/hooks/types.ts +++ b/applications/webapp/src/hooks/types.ts @@ -32,3 +32,19 @@ export type QueryConfigs = { schema: Joi.ObjectSchema; }; }; + +export type EditUserVariable = { + userInput: { + username: string; + firstName: string; + lastName: string; + }; +}; + +export type MutationConfigs = { + EDIT_USER: { + mutation: DocumentNode; + data: string; + variables: EditUserVariable; + }; +}; From f43115ff51dba99a6df07688ed082d572c31b692 Mon Sep 17 00:00:00 2001 From: Yonas Date: Wed, 1 Nov 2023 12:12:24 +0300 Subject: [PATCH 11/24] update configs --- applications/webapp/src/hooks/configs.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/applications/webapp/src/hooks/configs.ts b/applications/webapp/src/hooks/configs.ts index acf5ca0f..35604c90 100644 --- a/applications/webapp/src/hooks/configs.ts +++ b/applications/webapp/src/hooks/configs.ts @@ -10,9 +10,15 @@ * LICENSE file in the root directory of this source tree. */ +import { EditUserMutation } from "./mutation"; import { GET_USER_QUERY } from "./query"; import { userSchema } from "./schema"; -import { QueryConfigs, UserData } from "./types"; +import { + MutationConfigs, + QueryConfigs, + UserData, + EditUserVariable, +} from "./types"; export const queryConfigs: QueryConfigs = { GET_USER: { @@ -21,3 +27,11 @@ export const queryConfigs: QueryConfigs = { data: {} as UserData, }, }; + +export const mutationConfigs: MutationConfigs = { + EDIT_USER: { + mutation: EditUserMutation, + data: "", + variables: {} as EditUserVariable, + }, +}; From 3799d6b522ec9fffc1b55d0953e2a17e299c4c68 Mon Sep 17 00:00:00 2001 From: Yonas Date: Wed, 1 Nov 2023 13:17:21 +0300 Subject: [PATCH 12/24] add mutation hook --- .../webapp/src/hooks/useGenericMutation.ts | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 applications/webapp/src/hooks/useGenericMutation.ts diff --git a/applications/webapp/src/hooks/useGenericMutation.ts b/applications/webapp/src/hooks/useGenericMutation.ts new file mode 100644 index 00000000..2bab79aa --- /dev/null +++ b/applications/webapp/src/hooks/useGenericMutation.ts @@ -0,0 +1,36 @@ +/** + * Humanitech Supply Trail + * + * Copyright (c) Humanitech, Peter Rogov and Contributors + * + * Website: https://humanitech.net + * Repository: https://github.com/humanitech-net/supply-trail + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { ApolloError, useMutation } from "@apollo/client"; +import { MutationConfigs } from "./types"; +import { mutationConfigs } from "./configs"; + +export function useGenericMutation( + mutationType: T, + variables?: MutationConfigs[T]["variables"], +): { + callMutation: () => void; + data: MutationConfigs[T]["data"]; + loading: boolean; + error: ApolloError | undefined; +} { + const config = mutationConfigs[mutationType]; + const [mutate, { data, loading, error }] = useMutation(config.mutation); + + console.log(variables); + const callMutation = () => { + mutate({ + variables: variables, + }); + }; + return { callMutation, data, loading, error }; +} From af08b12ceec2ebda90ee9db4a953f8692b34d976 Mon Sep 17 00:00:00 2001 From: Yonas Date: Wed, 1 Nov 2023 14:19:15 +0300 Subject: [PATCH 13/24] refactor folder structure --- .../webapp/src/Pages/User/test/profileHolder.test.tsx | 2 +- applications/webapp/src/Pages/User/test/userPage.test.tsx | 2 +- applications/webapp/src/hooks/useGenericMutation.ts | 7 +++---- applications/webapp/src/hooks/useGenericQuery.ts | 4 ++-- applications/webapp/src/hooks/{ => util}/configs.ts | 0 applications/webapp/src/hooks/{ => util}/mutation.ts | 0 applications/webapp/src/hooks/{ => util}/query.ts | 0 applications/webapp/src/hooks/{ => util}/schema.ts | 0 applications/webapp/src/hooks/{ => util}/types.ts | 0 9 files changed, 7 insertions(+), 8 deletions(-) rename applications/webapp/src/hooks/{ => util}/configs.ts (100%) rename applications/webapp/src/hooks/{ => util}/mutation.ts (100%) rename applications/webapp/src/hooks/{ => util}/query.ts (100%) rename applications/webapp/src/hooks/{ => util}/schema.ts (100%) rename applications/webapp/src/hooks/{ => util}/types.ts (100%) diff --git a/applications/webapp/src/Pages/User/test/profileHolder.test.tsx b/applications/webapp/src/Pages/User/test/profileHolder.test.tsx index dbdc9eee..f47b5c02 100644 --- a/applications/webapp/src/Pages/User/test/profileHolder.test.tsx +++ b/applications/webapp/src/Pages/User/test/profileHolder.test.tsx @@ -17,7 +17,7 @@ import ProfileHolder from "../components/profileHolder"; import { UserPageContextProvider } from "../components/ContextProvider/UserPageContextProvider"; import { CardContextProvider } from "../components/ContextProvider/CardContextProvider"; import { MockedProvider } from "@apollo/client/testing"; -import { GET_USER_QUERY } from "../../../hooks/query"; +import { GET_USER_QUERY } from "../../../hooks/util/query"; describe("ProfileHolder", () => { const mockData = { diff --git a/applications/webapp/src/Pages/User/test/userPage.test.tsx b/applications/webapp/src/Pages/User/test/userPage.test.tsx index f3ff9e8c..550559b2 100644 --- a/applications/webapp/src/Pages/User/test/userPage.test.tsx +++ b/applications/webapp/src/Pages/User/test/userPage.test.tsx @@ -14,7 +14,7 @@ import React from "react"; import { render, fireEvent, screen, waitFor } from "@testing-library/react"; import UserPage from "../userPage"; import { MockedProvider } from "@apollo/client/testing"; -import { GET_USER_QUERY } from "../../../hooks/query"; +import { GET_USER_QUERY } from "../../../hooks/util/query"; import { BrowserRouter } from "react-router-dom"; describe("UserPage", () => { diff --git a/applications/webapp/src/hooks/useGenericMutation.ts b/applications/webapp/src/hooks/useGenericMutation.ts index 2bab79aa..9ff31328 100644 --- a/applications/webapp/src/hooks/useGenericMutation.ts +++ b/applications/webapp/src/hooks/useGenericMutation.ts @@ -11,8 +11,8 @@ */ import { ApolloError, useMutation } from "@apollo/client"; -import { MutationConfigs } from "./types"; -import { mutationConfigs } from "./configs"; +import { MutationConfigs } from "./util/types"; +import { mutationConfigs } from "./util/configs"; export function useGenericMutation( mutationType: T, @@ -26,8 +26,7 @@ export function useGenericMutation( const config = mutationConfigs[mutationType]; const [mutate, { data, loading, error }] = useMutation(config.mutation); - console.log(variables); - const callMutation = () => { + const callMutation = async () => { mutate({ variables: variables, }); diff --git a/applications/webapp/src/hooks/useGenericQuery.ts b/applications/webapp/src/hooks/useGenericQuery.ts index 8420b5af..d33015ae 100644 --- a/applications/webapp/src/hooks/useGenericQuery.ts +++ b/applications/webapp/src/hooks/useGenericQuery.ts @@ -10,8 +10,8 @@ * LICENSE file in the root directory of this source tree. */ -import { queryConfigs } from "./configs"; -import { QueryConfigs } from "./types"; +import { queryConfigs } from "./util/configs"; +import { QueryConfigs } from "./util/types"; import { ApolloError, useQuery } from "@apollo/client"; export default function useGenericQuery( diff --git a/applications/webapp/src/hooks/configs.ts b/applications/webapp/src/hooks/util/configs.ts similarity index 100% rename from applications/webapp/src/hooks/configs.ts rename to applications/webapp/src/hooks/util/configs.ts diff --git a/applications/webapp/src/hooks/mutation.ts b/applications/webapp/src/hooks/util/mutation.ts similarity index 100% rename from applications/webapp/src/hooks/mutation.ts rename to applications/webapp/src/hooks/util/mutation.ts diff --git a/applications/webapp/src/hooks/query.ts b/applications/webapp/src/hooks/util/query.ts similarity index 100% rename from applications/webapp/src/hooks/query.ts rename to applications/webapp/src/hooks/util/query.ts diff --git a/applications/webapp/src/hooks/schema.ts b/applications/webapp/src/hooks/util/schema.ts similarity index 100% rename from applications/webapp/src/hooks/schema.ts rename to applications/webapp/src/hooks/util/schema.ts diff --git a/applications/webapp/src/hooks/types.ts b/applications/webapp/src/hooks/util/types.ts similarity index 100% rename from applications/webapp/src/hooks/types.ts rename to applications/webapp/src/hooks/util/types.ts From 1868ab3b766de354fd30fca6a6c66f01124c2538 Mon Sep 17 00:00:00 2001 From: Yonas Date: Wed, 1 Nov 2023 14:21:20 +0300 Subject: [PATCH 14/24] add useUpdateUser hook --- .../webapp/src/hooks/useUpdateUser.ts | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 applications/webapp/src/hooks/useUpdateUser.ts diff --git a/applications/webapp/src/hooks/useUpdateUser.ts b/applications/webapp/src/hooks/useUpdateUser.ts new file mode 100644 index 00000000..97e08c12 --- /dev/null +++ b/applications/webapp/src/hooks/useUpdateUser.ts @@ -0,0 +1,35 @@ +/** + * Humanitech Supply Trail + * + * Copyright (c) Humanitech, Peter Rogov and Contributors + * + * Website: https://humanitech.net + * Repository: https://github.com/humanitech-net/supply-trail + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { useCardContext } from "src/Pages/User/context"; +import { useGenericMutation } from "./useGenericMutation"; + +type UserInput = { + userInput: { username: string; firstName: string; lastName: string }; +}; + +export default function useUpdateUser(userInput: UserInput) { + const mutate = useGenericMutation("EDIT_USER", userInput); + const { callMutation, data } = mutate; + + const card = useCardContext(); + + const { editable, setEditable, setElevation } = card; + + const updateUser = () => { + callMutation(); + setEditable(!editable); + setElevation(0); + }; + + return { updateUser, data }; +} From 5e5c0d1514813b5abb873bdc16ea2d0283a4e147 Mon Sep 17 00:00:00 2001 From: Yonas Date: Wed, 1 Nov 2023 14:28:16 +0300 Subject: [PATCH 15/24] update detailHolder --- .../Pages/User/components/detailHolder.tsx | 39 ++++++------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/applications/webapp/src/Pages/User/components/detailHolder.tsx b/applications/webapp/src/Pages/User/components/detailHolder.tsx index 6b4a51dc..7cba8bc4 100644 --- a/applications/webapp/src/Pages/User/components/detailHolder.tsx +++ b/applications/webapp/src/Pages/User/components/detailHolder.tsx @@ -21,12 +21,10 @@ import { Box, } from "@mui/material"; import { styles } from "../util/style"; -import { useMutation } from "@apollo/client"; -import { EditUserMutation } from "../../../hooks/mutation"; import { useCardContext, useUserContext } from "../context"; import { Link } from "react-router-dom"; import { CHANGE_PASSWORD_URL } from "../util/constants"; -// import useGenericMutation from "src/hooks/useGenericMutation"; +import useUpdateUser from "../../../hooks/useUpdateUser"; export default function DetailHolder() { const theme = useTheme(); @@ -37,32 +35,22 @@ export default function DetailHolder() { const { firstName, lastName, email, address, birthdate, phoneNumber } = user; const card = useCardContext(); - const { editable, setEditable, setElevation } = card; + const { editable } = card; const [firstname, setFirstname] = useState(firstName); const [lastname, setLastname] = useState(lastName); - const [editUser] = useMutation(EditUserMutation); - - async function updateUser() { - try { - const { data } = await editUser({ - variables: { - userInput: { - username: user.username, - firstName: firstname, - lastName: lastname, - }, - }, - }); - console.log("User:", data.editUser); - } catch (error) { - console.error("Error:", error); - } - setEditable(!editable); - setElevation(0); - } + const userInput = { + userInput: { + username: user.username, + firstName: firstname, + lastName: lastname, + }, + }; + + const { updateUser, data } = useUpdateUser(userInput); + console.log(data); function firstNameChanged( event: React.ChangeEvent, @@ -76,9 +64,6 @@ export default function DetailHolder() { return setLastname(event.target.value); } - // const mutate = useGenericMutation("EDIT_USER"); - // console.log(mutate); - return ( From 9aeaf28bef43571777eddff43a92d62dbd6074b4 Mon Sep 17 00:00:00 2001 From: Yonas Date: Fri, 3 Nov 2023 16:06:56 +0300 Subject: [PATCH 16/24] add grid item component --- .../components/userDetailHolderGridItem.tsx | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 applications/webapp/src/Pages/User/components/userDetailHolderGridItem.tsx diff --git a/applications/webapp/src/Pages/User/components/userDetailHolderGridItem.tsx b/applications/webapp/src/Pages/User/components/userDetailHolderGridItem.tsx new file mode 100644 index 00000000..7cde6d5c --- /dev/null +++ b/applications/webapp/src/Pages/User/components/userDetailHolderGridItem.tsx @@ -0,0 +1,38 @@ +/** + * Humanitech Supply Trail + * + * Copyright (c) Humanitech, Peter Rogov and Contributors + * + * Website: https://humanitech.net + * Repository: https://github.com/humanitech-net/supply-trail + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from "react"; +import { Grid, TextField } from "@mui/material"; +import { User } from "../../../Pages/interface"; +import { useCardContext } from "../context"; +import { labels } from "../util/constants"; + +export function UserDetailGridItem(props: { + user: User; + field: keyof User; + onChange: (field: keyof User, val: string) => void; +}) { + const { user, field, onChange } = props; + const card = useCardContext(); + + return ( + + onChange(field, e.target.value)} + /> + + ); +} From 1d97b96ef7a2c1bc308c255d1470b30c850a8487 Mon Sep 17 00:00:00 2001 From: Yonas Date: Fri, 3 Nov 2023 16:10:13 +0300 Subject: [PATCH 17/24] refactor detail holder --- .../Pages/User/components/detailHolder.tsx | 102 ++++-------------- .../{useUpdateUser.ts => useUpdateUser.tsx} | 28 ++++- 2 files changed, 43 insertions(+), 87 deletions(-) rename applications/webapp/src/hooks/{useUpdateUser.ts => useUpdateUser.tsx} (56%) diff --git a/applications/webapp/src/Pages/User/components/detailHolder.tsx b/applications/webapp/src/Pages/User/components/detailHolder.tsx index 7cba8bc4..dbe87094 100644 --- a/applications/webapp/src/Pages/User/components/detailHolder.tsx +++ b/applications/webapp/src/Pages/User/components/detailHolder.tsx @@ -16,15 +16,17 @@ import { CardContent, Grid, useTheme, - TextField, + // TextField, Button, Box, } from "@mui/material"; import { styles } from "../util/style"; import { useCardContext, useUserContext } from "../context"; import { Link } from "react-router-dom"; -import { CHANGE_PASSWORD_URL } from "../util/constants"; +import { CHANGE_PASSWORD_URL, fields } from "../util/constants"; import useUpdateUser from "../../../hooks/useUpdateUser"; +import { UserDetailGridItem } from "./userDetailHolderGridItem"; +import { User } from "../../interface"; export default function DetailHolder() { const theme = useTheme(); @@ -32,98 +34,34 @@ export default function DetailHolder() { const boxStyle = styles(theme).userPage; const { user } = useUserContext(); - const { firstName, lastName, email, address, birthdate, phoneNumber } = user; const card = useCardContext(); - const { editable } = card; + const { elevation } = card; - const [firstname, setFirstname] = useState(firstName); + const [updatedUser, setUpdatedUser] = useState(user); - const [lastname, setLastname] = useState(lastName); + const { updateUser } = useUpdateUser(updatedUser); - const userInput = { - userInput: { - username: user.username, - firstName: firstname, - lastName: lastname, - }, + const handleFieldChange = (field: keyof User, value: string) => { + setUpdatedUser((prevUserData) => ({ + ...prevUserData, + [field]: value, + })); }; - const { updateUser, data } = useUpdateUser(userInput); - console.log(data); - - function firstNameChanged( - event: React.ChangeEvent, - ) { - return setFirstname(event.target.value); - } - - function lastNameChanged( - event: React.ChangeEvent, - ) { - return setLastname(event.target.value); - } - return ( - + - - - - - - - - - - - - - - - - - - - - - - ( + - + ))} {!card.editable && ( diff --git a/applications/webapp/src/hooks/useUpdateUser.ts b/applications/webapp/src/hooks/useUpdateUser.tsx similarity index 56% rename from applications/webapp/src/hooks/useUpdateUser.ts rename to applications/webapp/src/hooks/useUpdateUser.tsx index 97e08c12..4604bb13 100644 --- a/applications/webapp/src/hooks/useUpdateUser.ts +++ b/applications/webapp/src/hooks/useUpdateUser.tsx @@ -10,16 +10,27 @@ * LICENSE file in the root directory of this source tree. */ +import React from "react"; import { useCardContext } from "src/Pages/User/context"; import { useGenericMutation } from "./useGenericMutation"; +import { User } from "../Pages/interface"; type UserInput = { userInput: { username: string; firstName: string; lastName: string }; }; -export default function useUpdateUser(userInput: UserInput) { +export default function useUpdateUser(newUserData: User) { + const userInput: UserInput = { + userInput: { + username: newUserData.username, + firstName: newUserData.firstName, + lastName: newUserData.lastName, + }, + }; + const mutate = useGenericMutation("EDIT_USER", userInput); - const { callMutation, data } = mutate; + + const { callMutation, data, loading, error } = mutate; const card = useCardContext(); @@ -27,9 +38,16 @@ export default function useUpdateUser(userInput: UserInput) { const updateUser = () => { callMutation(); - setEditable(!editable); - setElevation(0); + if (data) { + setEditable(!editable); + setElevation(0); + return <>data; + } + if (loading) { + <>loading; + } + return <>error; }; - return { updateUser, data }; + return { updateUser, data, loading, error }; } From 994818a33ef16dabb7b10d8444a54afd4ead2459 Mon Sep 17 00:00:00 2001 From: Yonas Date: Fri, 3 Nov 2023 17:00:22 +0300 Subject: [PATCH 18/24] update constants --- .../webapp/src/Pages/User/util/constants.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/applications/webapp/src/Pages/User/util/constants.ts b/applications/webapp/src/Pages/User/util/constants.ts index 0db1d5cc..0d567574 100644 --- a/applications/webapp/src/Pages/User/util/constants.ts +++ b/applications/webapp/src/Pages/User/util/constants.ts @@ -10,5 +10,25 @@ * LICENSE file in the root directory of this source tree. */ +import { User } from "../../../Pages/interface"; + export const CHANGE_PASSWORD_URL = "https://dev.supply-trail.humanitech.net/auth/realms/humanitech/protocol/openid-connect/auth?response_type=code&client_id=supply-trail-app&kc_action=UPDATE_PASSWORD"; + +export const labels: Partial> = { + firstName: "First Name", + lastName: "Last Name", + email: "Email", + phoneNumber: "Phone Number", + address: "Address", + birthdate: "Birth Date", +}; + +export const fields: Array = [ + "firstName", + "lastName", + "email", + "phoneNumber", + "address", + "birthdate", +]; From 793d090444081bc095bc4cf81959da9f93b6b295 Mon Sep 17 00:00:00 2001 From: Yonas Date: Mon, 6 Nov 2023 16:43:41 +0300 Subject: [PATCH 19/24] remove code smell --- .../Home/ContextProvider/drawerProvider.tsx | 8 ++++---- .../LeftDrawer/Components/drawerHeader.tsx | 18 +++++++++++++++--- .../Home/LeftDrawer/Components/drawerMenu.tsx | 12 ++++++++++++ .../src/Pages/Home/LeftDrawer/leftDrawer.tsx | 1 - .../Pages/Home/LeftDrawer/util/constants.ts | 12 ++++++++++++ .../src/Pages/Home/LeftDrawer/util/style.ts | 12 +++++++++++- .../src/Pages/Home/MainContent/mainContent.tsx | 4 +++- .../src/Pages/User/components/detailHolder.tsx | 10 +--------- .../components/userDetailHolderGridItem.tsx | 12 +++++++----- .../webapp/src/hooks/useGenericMutation.ts | 4 ++-- .../webapp/src/hooks/useUpdateUser.tsx | 2 +- 11 files changed, 68 insertions(+), 27 deletions(-) diff --git a/applications/webapp/src/Pages/Home/ContextProvider/drawerProvider.tsx b/applications/webapp/src/Pages/Home/ContextProvider/drawerProvider.tsx index 37221fc7..8cb43825 100644 --- a/applications/webapp/src/Pages/Home/ContextProvider/drawerProvider.tsx +++ b/applications/webapp/src/Pages/Home/ContextProvider/drawerProvider.tsx @@ -10,7 +10,7 @@ * LICENSE file in the root directory of this source tree. */ -import React, { ReactNode, createContext, useState } from "react"; +import React, { ReactNode, createContext, useState, useMemo } from "react"; interface DrawerContextProps { open: boolean; @@ -29,9 +29,9 @@ export const DrawerContext = createContext({ export const DrawerProvider: React.FC = ({ children }) => { const [open, setOpen] = useState(false); + const props = useMemo(() => ({ open, setOpen }), [open, setOpen]); + return ( - - {children} - + {children} ); }; diff --git a/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerHeader.tsx b/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerHeader.tsx index cdded107..d1b7f681 100644 --- a/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerHeader.tsx +++ b/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerHeader.tsx @@ -1,3 +1,15 @@ +/** + * Humanitech Supply Trail + * + * Copyright (c) Humanitech, Peter Rogov and Contributors + * + * Website: https://humanitech.net + * Repository: https://github.com/humanitech-net/supply-trail + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + import React, { useContext } from "react"; import { IconButton, styled } from "@mui/material"; @@ -11,7 +23,7 @@ export default function DrawerHeader() { setOpen(false); }; - const DrawerHeader = styled("div")(({ theme }) => ({ + const Header = styled("div")(({ theme }) => ({ display: "flex", alignItems: "center", padding: theme.spacing(0, 1), @@ -22,7 +34,7 @@ export default function DrawerHeader() { })); return ( - +
- +
); } diff --git a/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerMenu.tsx b/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerMenu.tsx index 8a3dc1c8..27e71521 100644 --- a/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerMenu.tsx +++ b/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerMenu.tsx @@ -1,3 +1,15 @@ +/** + * Humanitech Supply Trail + * + * Copyright (c) Humanitech, Peter Rogov and Contributors + * + * Website: https://humanitech.net + * Repository: https://github.com/humanitech-net/supply-trail + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + import React from "react"; import { List, ListItem, ListItemButton, ListItemText } from "@mui/material"; import { drawerMenu } from "../util/constants"; diff --git a/applications/webapp/src/Pages/Home/LeftDrawer/leftDrawer.tsx b/applications/webapp/src/Pages/Home/LeftDrawer/leftDrawer.tsx index 6a0d92f7..2986751b 100644 --- a/applications/webapp/src/Pages/Home/LeftDrawer/leftDrawer.tsx +++ b/applications/webapp/src/Pages/Home/LeftDrawer/leftDrawer.tsx @@ -18,7 +18,6 @@ import DrawerHeader from "./Components/drawerHeader"; import DrawerMenu from "./Components/drawerMenu"; import { styles } from "./util/style"; import { DrawerContext } from "../ContextProvider/drawerProvider"; -// import { DrawerContext } from "./Components/DrawerContextProvider"; export default function LeftDrawer() { const theme = useTheme(); diff --git a/applications/webapp/src/Pages/Home/LeftDrawer/util/constants.ts b/applications/webapp/src/Pages/Home/LeftDrawer/util/constants.ts index 54763e6c..382f0b5b 100644 --- a/applications/webapp/src/Pages/Home/LeftDrawer/util/constants.ts +++ b/applications/webapp/src/Pages/Home/LeftDrawer/util/constants.ts @@ -1,3 +1,15 @@ +/** + * Humanitech Supply Trail + * + * Copyright (c) Humanitech, Peter Rogov and Contributors + * + * Website: https://humanitech.net + * Repository: https://github.com/humanitech-net/supply-trail + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + export const drawerMenu = [ "Supply", "Tracking", diff --git a/applications/webapp/src/Pages/Home/LeftDrawer/util/style.ts b/applications/webapp/src/Pages/Home/LeftDrawer/util/style.ts index 694a692e..6d7e10a7 100644 --- a/applications/webapp/src/Pages/Home/LeftDrawer/util/style.ts +++ b/applications/webapp/src/Pages/Home/LeftDrawer/util/style.ts @@ -1,4 +1,14 @@ -// import { Theme } from "@emotion/react"; +/** + * Humanitech Supply Trail + * + * Copyright (c) Humanitech, Peter Rogov and Contributors + * + * Website: https://humanitech.net + * Repository: https://github.com/humanitech-net/supply-trail + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ export const styles = () => ({ drawer: { diff --git a/applications/webapp/src/Pages/Home/MainContent/mainContent.tsx b/applications/webapp/src/Pages/Home/MainContent/mainContent.tsx index 7ca35f43..a73ba3a8 100644 --- a/applications/webapp/src/Pages/Home/MainContent/mainContent.tsx +++ b/applications/webapp/src/Pages/Home/MainContent/mainContent.tsx @@ -23,8 +23,10 @@ export default function MainContent() { const theme = useTheme(); const isDesktop = useMediaQuery(theme.breakpoints.up("md")); + const leftMargin = 240; + const Main = styled("main")(({ theme }) => ({ - marginLeft: open && isDesktop ? 240 : 0, + marginLeft: open && isDesktop ? leftMargin : 0, marginTop: 80, flexGrow: 1, transition: theme.transitions.create("margin", { diff --git a/applications/webapp/src/Pages/User/components/detailHolder.tsx b/applications/webapp/src/Pages/User/components/detailHolder.tsx index dbe87094..a0bb3391 100644 --- a/applications/webapp/src/Pages/User/components/detailHolder.tsx +++ b/applications/webapp/src/Pages/User/components/detailHolder.tsx @@ -11,15 +11,7 @@ */ import React, { useState } from "react"; -import { - Card, - CardContent, - Grid, - useTheme, - // TextField, - Button, - Box, -} from "@mui/material"; +import { Card, CardContent, Grid, useTheme, Button, Box } from "@mui/material"; import { styles } from "../util/style"; import { useCardContext, useUserContext } from "../context"; import { Link } from "react-router-dom"; diff --git a/applications/webapp/src/Pages/User/components/userDetailHolderGridItem.tsx b/applications/webapp/src/Pages/User/components/userDetailHolderGridItem.tsx index 7cde6d5c..32221db9 100644 --- a/applications/webapp/src/Pages/User/components/userDetailHolderGridItem.tsx +++ b/applications/webapp/src/Pages/User/components/userDetailHolderGridItem.tsx @@ -16,11 +16,13 @@ import { User } from "../../../Pages/interface"; import { useCardContext } from "../context"; import { labels } from "../util/constants"; -export function UserDetailGridItem(props: { - user: User; - field: keyof User; - onChange: (field: keyof User, val: string) => void; -}) { +export function UserDetailGridItem( + props: Readonly<{ + user: User; + field: keyof User; + onChange: (field: keyof User, val: string) => void; + }>, +) { const { user, field, onChange } = props; const card = useCardContext(); diff --git a/applications/webapp/src/hooks/useGenericMutation.ts b/applications/webapp/src/hooks/useGenericMutation.ts index 9ff31328..e7daad11 100644 --- a/applications/webapp/src/hooks/useGenericMutation.ts +++ b/applications/webapp/src/hooks/useGenericMutation.ts @@ -16,7 +16,7 @@ import { mutationConfigs } from "./util/configs"; export function useGenericMutation( mutationType: T, - variables?: MutationConfigs[T]["variables"], + mutationVariables?: MutationConfigs[T]["variables"], ): { callMutation: () => void; data: MutationConfigs[T]["data"]; @@ -28,7 +28,7 @@ export function useGenericMutation( const callMutation = async () => { mutate({ - variables: variables, + variables: mutationVariables, }); }; return { callMutation, data, loading, error }; diff --git a/applications/webapp/src/hooks/useUpdateUser.tsx b/applications/webapp/src/hooks/useUpdateUser.tsx index 4604bb13..54a2ea03 100644 --- a/applications/webapp/src/hooks/useUpdateUser.tsx +++ b/applications/webapp/src/hooks/useUpdateUser.tsx @@ -44,7 +44,7 @@ export default function useUpdateUser(newUserData: User) { return <>data; } if (loading) { - <>loading; + return <>loading; } return <>error; }; From 1a4b2ab65227dc2b5aa95c9f7c9a4db883b2d47b Mon Sep 17 00:00:00 2001 From: Yonas Date: Sun, 12 Nov 2023 03:04:54 +0300 Subject: [PATCH 20/24] update custom mutation hook --- applications/webapp/src/hooks/useGenericMutation.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/applications/webapp/src/hooks/useGenericMutation.ts b/applications/webapp/src/hooks/useGenericMutation.ts index 9ff31328..ac8028a7 100644 --- a/applications/webapp/src/hooks/useGenericMutation.ts +++ b/applications/webapp/src/hooks/useGenericMutation.ts @@ -16,9 +16,10 @@ import { mutationConfigs } from "./util/configs"; export function useGenericMutation( mutationType: T, - variables?: MutationConfigs[T]["variables"], ): { - callMutation: () => void; + callMutation: ( + mutationVariables: MutationConfigs[T]["variables"], + ) => Promise; data: MutationConfigs[T]["data"]; loading: boolean; error: ApolloError | undefined; @@ -26,9 +27,11 @@ export function useGenericMutation( const config = mutationConfigs[mutationType]; const [mutate, { data, loading, error }] = useMutation(config.mutation); - const callMutation = async () => { + const callMutation = async ( + mutationVariables: MutationConfigs[T]["variables"], + ) => { mutate({ - variables: variables, + variables: mutationVariables, }); }; return { callMutation, data, loading, error }; From 297e1e072fc33f5627b28a52de94b2833527f6c3 Mon Sep 17 00:00:00 2001 From: Yonas Date: Sun, 12 Nov 2023 03:20:41 +0300 Subject: [PATCH 21/24] add useUserEntry hook --- .../webapp/src/hooks/useUpdateUser.tsx | 53 ------------------- applications/webapp/src/hooks/useUserEntry.ts | 42 +++++++++++++++ 2 files changed, 42 insertions(+), 53 deletions(-) delete mode 100644 applications/webapp/src/hooks/useUpdateUser.tsx create mode 100644 applications/webapp/src/hooks/useUserEntry.ts diff --git a/applications/webapp/src/hooks/useUpdateUser.tsx b/applications/webapp/src/hooks/useUpdateUser.tsx deleted file mode 100644 index 4604bb13..00000000 --- a/applications/webapp/src/hooks/useUpdateUser.tsx +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Humanitech Supply Trail - * - * Copyright (c) Humanitech, Peter Rogov and Contributors - * - * Website: https://humanitech.net - * Repository: https://github.com/humanitech-net/supply-trail - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import React from "react"; -import { useCardContext } from "src/Pages/User/context"; -import { useGenericMutation } from "./useGenericMutation"; -import { User } from "../Pages/interface"; - -type UserInput = { - userInput: { username: string; firstName: string; lastName: string }; -}; - -export default function useUpdateUser(newUserData: User) { - const userInput: UserInput = { - userInput: { - username: newUserData.username, - firstName: newUserData.firstName, - lastName: newUserData.lastName, - }, - }; - - const mutate = useGenericMutation("EDIT_USER", userInput); - - const { callMutation, data, loading, error } = mutate; - - const card = useCardContext(); - - const { editable, setEditable, setElevation } = card; - - const updateUser = () => { - callMutation(); - if (data) { - setEditable(!editable); - setElevation(0); - return <>data; - } - if (loading) { - <>loading; - } - return <>error; - }; - - return { updateUser, data, loading, error }; -} diff --git a/applications/webapp/src/hooks/useUserEntry.ts b/applications/webapp/src/hooks/useUserEntry.ts new file mode 100644 index 00000000..1eb045b5 --- /dev/null +++ b/applications/webapp/src/hooks/useUserEntry.ts @@ -0,0 +1,42 @@ +/** + * Humanitech Supply Trail + * + * Copyright (c) Humanitech, Peter Rogov and Contributors + * + * Website: https://humanitech.net + * Repository: https://github.com/humanitech-net/supply-trail + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { useMemo } from "react"; +import { useGenericMutation } from "./useGenericMutation"; +import { EditUserVariable } from "./util/types"; + +export default function useUserEntry() { + const { callMutation, data, loading, error } = + useGenericMutation("EDIT_USER"); + + const update = async (newUserData: EditUserVariable) => { + callMutation(newUserData); + }; + + const { username, firstName, lastName } = data?.editUser ?? {}; + + const user = useMemo( + () => ({ + username: username ?? "", + firstName: firstName ?? "", + lastName: lastName ?? "", + email: "email", + birthdate: "birthdate", + address: "address", + phoneNumber: "123456789", + description: `I am ${firstName}`, + }), + [username, firstName, lastName], + ); + + return { user, loading, error, update }; +} From 66943ec8e7d2d254a4e32f0bb492a8960e95891b Mon Sep 17 00:00:00 2001 From: Yonas Date: Sun, 12 Nov 2023 03:27:33 +0300 Subject: [PATCH 22/24] update UserPageContextProovider --- .../UserPageContextProvider.tsx | 24 +++++++++++++++-- .../webapp/src/Pages/User/context.tsx | 11 ++------ applications/webapp/src/hooks/util/configs.ts | 3 ++- .../webapp/src/hooks/util/mutation.ts | 6 ++++- applications/webapp/src/hooks/util/types.ts | 26 ++++++++++++++++++- 5 files changed, 56 insertions(+), 14 deletions(-) diff --git a/applications/webapp/src/Pages/User/components/ContextProvider/UserPageContextProvider.tsx b/applications/webapp/src/Pages/User/components/ContextProvider/UserPageContextProvider.tsx index 004e4de0..7535511b 100644 --- a/applications/webapp/src/Pages/User/components/ContextProvider/UserPageContextProvider.tsx +++ b/applications/webapp/src/Pages/User/components/ContextProvider/UserPageContextProvider.tsx @@ -10,22 +10,42 @@ * LICENSE file in the root directory of this source tree. */ -import React, { useMemo } from "react"; +import React, { useMemo, useState } from "react"; import { useCurrentUserData } from "../../../../hooks/useCurrentUserData"; import { UserContext } from "../../context"; +import useUserEntry from "../../../../hooks/useUserEntry"; export function UserPageContextProvider({ children, }: Readonly<{ children: React.ReactNode; }>) { - const { user, loading, error } = useCurrentUserData(); + const { + user: initialUser, + loading: queryLoading, + error: queryError, + } = useCurrentUserData(); + + const { + update, + user: updatedUser, + loading: mutationLoading, + error: mutationError, + } = useUserEntry(); + + const [userUpdated, setUserUpdated] = useState(false); + + const user = userUpdated ? updatedUser : initialUser; + const loading = userUpdated ? mutationLoading : queryLoading; + const error = userUpdated ? mutationError : queryError; const userpagecontext = useMemo( () => ({ user, loading, error, + setUserUpdated, + update, }), [user, loading, error], ); diff --git a/applications/webapp/src/Pages/User/context.tsx b/applications/webapp/src/Pages/User/context.tsx index a69d736c..8baa7788 100644 --- a/applications/webapp/src/Pages/User/context.tsx +++ b/applications/webapp/src/Pages/User/context.tsx @@ -12,15 +12,8 @@ import { createContext, useContext } from "react"; -import { Card, User } from "../interface"; -import { ApolloError } from "@apollo/client"; - -type UserContextType = { - user: User; - loading: boolean; - error: ApolloError | undefined; -}; - +import { Card } from "../interface"; +import { UserContextType } from "../../hooks/util/types"; export const UserContext = createContext( undefined, ); diff --git a/applications/webapp/src/hooks/util/configs.ts b/applications/webapp/src/hooks/util/configs.ts index 35604c90..697c4588 100644 --- a/applications/webapp/src/hooks/util/configs.ts +++ b/applications/webapp/src/hooks/util/configs.ts @@ -18,6 +18,7 @@ import { QueryConfigs, UserData, EditUserVariable, + EditData, } from "./types"; export const queryConfigs: QueryConfigs = { @@ -31,7 +32,7 @@ export const queryConfigs: QueryConfigs = { export const mutationConfigs: MutationConfigs = { EDIT_USER: { mutation: EditUserMutation, - data: "", + data: {} as EditData, variables: {} as EditUserVariable, }, }; diff --git a/applications/webapp/src/hooks/util/mutation.ts b/applications/webapp/src/hooks/util/mutation.ts index 62a1b412..7e544143 100644 --- a/applications/webapp/src/hooks/util/mutation.ts +++ b/applications/webapp/src/hooks/util/mutation.ts @@ -14,6 +14,10 @@ import { gql } from "@apollo/client"; export const EditUserMutation = gql` mutation EditUser($userInput: UpdateUser!) { - editUser(userInput: $userInput) + editUser(userInput: $userInput) { + username + firstName + lastName + } } `; diff --git a/applications/webapp/src/hooks/util/types.ts b/applications/webapp/src/hooks/util/types.ts index 91194e5a..2fd5fab1 100644 --- a/applications/webapp/src/hooks/util/types.ts +++ b/applications/webapp/src/hooks/util/types.ts @@ -12,6 +12,8 @@ import Joi from "joi"; import { DocumentNode } from "@apollo/client"; +import { ApolloError } from "@apollo/client"; +import { User } from "../../Pages/interface"; export type UserData = { getUser: { @@ -44,7 +46,29 @@ export type EditUserVariable = { export type MutationConfigs = { EDIT_USER: { mutation: DocumentNode; - data: string; + data: EditData; variables: EditUserVariable; }; }; + +export type UserContextType = { + user: User; + loading: boolean; + error: ApolloError | undefined; + update: (newUserData: EditUserVariable) => Promise; + setUserUpdated: React.Dispatch>; +}; + +export type EditData = { + editUser: { + id?: string; + username: string; + firstName: string; + lastName: string; + email?: string; + }; +}; + +export type UserInput = { + userInput: { username: string; firstName: string; lastName: string }; +}; From f469ba21b404d62261bb0466274539055dd94228 Mon Sep 17 00:00:00 2001 From: Yonas Date: Sun, 12 Nov 2023 03:30:38 +0300 Subject: [PATCH 23/24] update detailHolder --- .../Pages/User/components/detailHolder.tsx | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/applications/webapp/src/Pages/User/components/detailHolder.tsx b/applications/webapp/src/Pages/User/components/detailHolder.tsx index dbe87094..227e42f3 100644 --- a/applications/webapp/src/Pages/User/components/detailHolder.tsx +++ b/applications/webapp/src/Pages/User/components/detailHolder.tsx @@ -11,20 +11,11 @@ */ import React, { useState } from "react"; -import { - Card, - CardContent, - Grid, - useTheme, - // TextField, - Button, - Box, -} from "@mui/material"; +import { Card, CardContent, Grid, useTheme, Button, Box } from "@mui/material"; import { styles } from "../util/style"; import { useCardContext, useUserContext } from "../context"; import { Link } from "react-router-dom"; import { CHANGE_PASSWORD_URL, fields } from "../util/constants"; -import useUpdateUser from "../../../hooks/useUpdateUser"; import { UserDetailGridItem } from "./userDetailHolderGridItem"; import { User } from "../../interface"; @@ -33,14 +24,18 @@ export default function DetailHolder() { const style = styles(theme).detailHolder; const boxStyle = styles(theme).userPage; - const { user } = useUserContext(); - - const card = useCardContext(); - const { elevation } = card; - + const { user, update, setUserUpdated } = useUserContext(); + const { elevation } = useCardContext(); const [updatedUser, setUpdatedUser] = useState(user); + const { editable, setEditable, setElevation } = useCardContext(); - const { updateUser } = useUpdateUser(updatedUser); + const newUserData = { + userInput: { + username: updatedUser.username, + firstName: updatedUser.firstName, + lastName: updatedUser.lastName, + }, + }; const handleFieldChange = (field: keyof User, value: string) => { setUpdatedUser((prevUserData) => ({ @@ -49,6 +44,14 @@ export default function DetailHolder() { })); }; + const onClickUpdate = async () => { + await update(newUserData).then(() => { + setEditable(!editable); + setElevation(0); + setUserUpdated(true); + }); + }; + return ( @@ -63,10 +66,10 @@ export default function DetailHolder() { /> ))} - {!card.editable && ( + {!editable && ( - From 4b77d1e69292774a99cf0436897c163961d96597 Mon Sep 17 00:00:00 2001 From: Yonas Date: Sun, 12 Nov 2023 04:33:37 +0300 Subject: [PATCH 24/24] remove code smell --- .../LeftDrawer/Components/drawerHeader.tsx | 6 +++--- .../webapp/src/Pages/Home/NavBar/navbar.tsx | 4 ++-- .../webapp/src/Pages/Home/home.test.tsx | 5 +++-- .../Pages/User/components/detailHolder.tsx | 19 +++++++++++-------- .../components/userDetailHolderGridItem.tsx | 9 ++++++++- applications/webapp/src/hooks/util/types.ts | 3 +-- 6 files changed, 28 insertions(+), 18 deletions(-) diff --git a/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerHeader.tsx b/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerHeader.tsx index d1b7f681..3bee4700 100644 --- a/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerHeader.tsx +++ b/applications/webapp/src/Pages/Home/LeftDrawer/Components/drawerHeader.tsx @@ -17,11 +17,11 @@ import MenuIcon from "@mui/icons-material/Menu"; import { DrawerContext } from "../../ContextProvider/drawerProvider"; export default function DrawerHeader() { - const { setOpen } = useContext(DrawerContext); + const { open, setOpen } = useContext(DrawerContext); - const closeDrawer = () => { + const closeDrawer = React.useCallback(() => { setOpen(false); - }; + }, [open]); const Header = styled("div")(({ theme }) => ({ display: "flex", diff --git a/applications/webapp/src/Pages/Home/NavBar/navbar.tsx b/applications/webapp/src/Pages/Home/NavBar/navbar.tsx index 57642a63..6f31d2d9 100644 --- a/applications/webapp/src/Pages/Home/NavBar/navbar.tsx +++ b/applications/webapp/src/Pages/Home/NavBar/navbar.tsx @@ -49,9 +49,9 @@ const AppBar = styled(MuiAppBar, { export default function NavBar() { const { open, setOpen } = useContext(DrawerContext); - const openDrawer = () => { + const openDrawer = React.useCallback(() => { setOpen(true); - }; + }, [open]); return ( { + const openDrawerLabel = "open drawer"; test("renders navbar", () => { const { getByLabelText } = render( @@ -32,7 +33,7 @@ describe("Home", () => { , ); - const OpenDrawerButton = getByLabelText("open drawer"); + const OpenDrawerButton = getByLabelText(openDrawerLabel); fireEvent.click(OpenDrawerButton); const Drawer = getByLabelText("drawer"); @@ -46,7 +47,7 @@ describe("Home", () => { , ); - const OpenDrawerButton = getByLabelText("open drawer"); + const OpenDrawerButton = getByLabelText(openDrawerLabel); fireEvent.click(OpenDrawerButton); const CloseDrawerButton = getByLabelText("close drawer"); diff --git a/applications/webapp/src/Pages/User/components/detailHolder.tsx b/applications/webapp/src/Pages/User/components/detailHolder.tsx index 227e42f3..f1b773e7 100644 --- a/applications/webapp/src/Pages/User/components/detailHolder.tsx +++ b/applications/webapp/src/Pages/User/components/detailHolder.tsx @@ -37,20 +37,23 @@ export default function DetailHolder() { }, }; - const handleFieldChange = (field: keyof User, value: string) => { - setUpdatedUser((prevUserData) => ({ - ...prevUserData, - [field]: value, - })); - }; + const handleFieldChange = React.useCallback( + (field: keyof User, value: string) => { + setUpdatedUser((prevUserData) => ({ + ...prevUserData, + [field]: value, + })); + }, + [setUpdatedUser], + ); - const onClickUpdate = async () => { + const onClickUpdate = React.useCallback(async () => { await update(newUserData).then(() => { setEditable(!editable); setElevation(0); setUserUpdated(true); }); - }; + }, [newUserData]); return ( diff --git a/applications/webapp/src/Pages/User/components/userDetailHolderGridItem.tsx b/applications/webapp/src/Pages/User/components/userDetailHolderGridItem.tsx index 32221db9..8e127d88 100644 --- a/applications/webapp/src/Pages/User/components/userDetailHolderGridItem.tsx +++ b/applications/webapp/src/Pages/User/components/userDetailHolderGridItem.tsx @@ -26,6 +26,13 @@ export function UserDetailGridItem( const { user, field, onChange } = props; const card = useCardContext(); + const updateValue = React.useCallback( + (event: React.ChangeEvent) => { + onChange(field, event.target.value); + }, + [field], + ); + return ( onChange(field, e.target.value)} + onChange={updateValue} /> ); diff --git a/applications/webapp/src/hooks/util/types.ts b/applications/webapp/src/hooks/util/types.ts index 2fd5fab1..c0d17d6b 100644 --- a/applications/webapp/src/hooks/util/types.ts +++ b/applications/webapp/src/hooks/util/types.ts @@ -11,8 +11,7 @@ */ import Joi from "joi"; -import { DocumentNode } from "@apollo/client"; -import { ApolloError } from "@apollo/client"; +import { DocumentNode, ApolloError } from "@apollo/client"; import { User } from "../../Pages/interface"; export type UserData = {