From c90c1d0a38fec7c763d1a62cf0011368e855cfc6 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Thu, 28 Mar 2024 15:02:26 -0400 Subject: [PATCH 01/24] feat: Added api call to get all members --- src/components/TableDashboard.tsx | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/components/TableDashboard.tsx b/src/components/TableDashboard.tsx index 486e0ad..83aaaba 100644 --- a/src/components/TableDashboard.tsx +++ b/src/components/TableDashboard.tsx @@ -1,10 +1,16 @@ import { Table, Thead, Tbody, Tr, Th, TableContainer } from '@chakra-ui/react' +import { getAllUsers } from '../api/lib/users' +import { type User } from '../types/index' import React from 'react' -// eslint-disable-next-line import/extensions -import sampleUserData from '../sample_data.json' function TableDashboard (): JSX.Element { - const [sampleData] = React.useState(sampleUserData) + const [members, setMembers] = React.useState([]) + + React.useEffect(() => { + void getAllUsers().then((response) => { + setMembers(response.data as User[]) + }) + }, []) return ( @@ -18,16 +24,16 @@ function TableDashboard (): JSX.Element { - {sampleData && Object.values(sampleData.Users) + {members .sort((a, b) => { - return a.Displayname.localeCompare(b.Displayname) - }).filter((user) => !user.Disabled) - .map(({ Displayname, Email, Disabled }) => - - {Displayname} - {Email} + return a.displayName.localeCompare(b.displayName) + }).filter((user) => !user.enabled) + .map(({ displayName, email, enabled }) => + + {displayName} + {email} - {Disabled ? 'Inactive' : 'Active'} + {enabled ? 'Inactive' : 'Active'} )} From 314cb67b5e68ffc4887e0294bea75854da1bf189 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Thu, 28 Mar 2024 15:33:29 -0400 Subject: [PATCH 02/24] feat: Added error handling to api calls --- src/api/lib/users.tsx | 70 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 7 deletions(-) diff --git a/src/api/lib/users.tsx b/src/api/lib/users.tsx index 12e94e2..9beecd3 100644 --- a/src/api/lib/users.tsx +++ b/src/api/lib/users.tsx @@ -1,27 +1,83 @@ -import { type AxiosResponse } from 'axios' +import { type AxiosResponse, AxiosError } from 'axios' import request from '../apiClient' import type { User } from '../../types/index' +const API_NAME = 'User Management' + export const getAllUsers = async (): Promise => { - return await request('GET', '/v1/users/all') + try { + const response = await request('GET', '/v1/users/all') + return response + } catch (error) { + if (error instanceof AxiosError) { + console.error(`${API_NAME} Error: ${error.message}`, error.response?.data) + throw new Error(`${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}`) + } + throw new Error('Unknown Error') + } } export const getUser = async (username: string): Promise => { - return await request('GET', `/v1/users/user?username=${username}`) + try { + const response = await request('GET', `/v1/users/user?username=${username}`) + return response + } catch (error) { + if (error instanceof AxiosError) { + console.error(`${API_NAME} Error: ${error.message}`, error.response?.data) + throw new Error(`${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}`) + } + throw new Error('Unknown Error') + } } export const addUser = async (user: User): Promise => { - return await request('POST', '/v1/users/user', JSON.stringify(user)) + try { + const response = await request('POST', '/v1/users/user', JSON.stringify(user)) + return response + } catch (error) { + if (error instanceof AxiosError) { + console.error(`${API_NAME} Error: ${error.message}`, error.response?.data) + throw new Error(`${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}`) + } + throw new Error('Unknown Error') + } } export const updateUser = async (username: string, user: User): Promise => { - return await request('PUT', `/v1/users/user?username=${username}`, JSON.stringify(user)) + try { + const response = await request('PUT', `/v1/users/user?username=${username}`, JSON.stringify(user)) + return response + } catch (error) { + if (error instanceof AxiosError) { + console.error(`${API_NAME} Error: ${error.message}`, error.response?.data) + throw new Error(`${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}`) + } + throw new Error('Unknown Error') + } } export const deleteUser = async (username: string): Promise => { - return await request('DELETE', `/v1/users/user?username=${username}`) + try { + const response = await request('DELETE', `/v1/users/user?username=${username}`) + return response + } catch (error) { + if (error instanceof AxiosError) { + console.error(`${API_NAME} Error: ${error.message}`, error.response?.data) + throw new Error(`${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}`) + } + throw new Error('Unknown Error') + } } export const getMemberSizeWeeklyChange = async (): Promise => { - return await request('GET', '/v1/users/member-size-weekly-change') + try { + const response = await request('GET', '/v1/users/memberSizeWeeklyChange') + return response + } catch (error) { + if (error instanceof AxiosError) { + console.error(`${API_NAME} Error: ${error.message}`, error.response?.data) + throw new Error(`${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}`) + } + throw new Error('Unknown Error') + } } From 9c7d042f46a692ce17b9fa7e7b80b76beaac0d6b Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Thu, 28 Mar 2024 15:44:31 -0400 Subject: [PATCH 03/24] feat: Moved API call to Home Page --- src/components/TableDashboard.tsx | 17 ++++------------- src/pages/HomePage.tsx | 13 ++++++++++++- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/components/TableDashboard.tsx b/src/components/TableDashboard.tsx index 83aaaba..454f03e 100644 --- a/src/components/TableDashboard.tsx +++ b/src/components/TableDashboard.tsx @@ -1,17 +1,8 @@ import { Table, Thead, Tbody, Tr, Th, TableContainer } from '@chakra-ui/react' -import { getAllUsers } from '../api/lib/users' import { type User } from '../types/index' import React from 'react' -function TableDashboard (): JSX.Element { - const [members, setMembers] = React.useState([]) - - React.useEffect(() => { - void getAllUsers().then((response) => { - setMembers(response.data as User[]) - }) - }, []) - +function TableDashboard ({ members }: { members: User[] }): JSX.Element { return ( @@ -25,10 +16,10 @@ function TableDashboard (): JSX.Element { {members - .sort((a, b) => { + .sort((a: User, b: User) => { return a.displayName.localeCompare(b.displayName) - }).filter((user) => !user.enabled) - .map(({ displayName, email, enabled }) => + }).filter((user: User) => !user.enabled) + .map(({ displayName, email, enabled }: User) => // Add type annotation for User diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index ed57d22..fd02177 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -1,13 +1,24 @@ import { Container, HStack } from '@chakra-ui/react' import TableDashboard from '../components/TableDashboard' import Sidebar from '../components/Sidebar' +import { getAllUsers } from '../api/lib/users' +import { type User } from '../types/index' +import React, { useEffect } from 'react' function HomePage (): JSX.Element { + const [members, setMembers] = React.useState([]) + + useEffect(() => { + void getAllUsers().then((response) => { + setMembers(response.data as User[]) + }) + }, []) + return ( - + ) From 3ba975e2fe6fe4d902f93724146bd823d552abc3 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Thu, 28 Mar 2024 15:49:03 -0400 Subject: [PATCH 04/24] feat: Added alert message on failed API call --- src/pages/HomePage.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index fd02177..9c15a47 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -1,16 +1,20 @@ -import { Container, HStack } from '@chakra-ui/react' +import { Container, HStack, Text } from '@chakra-ui/react' import TableDashboard from '../components/TableDashboard' import Sidebar from '../components/Sidebar' import { getAllUsers } from '../api/lib/users' import { type User } from '../types/index' -import React, { useEffect } from 'react' +import React, { useEffect, useState } from 'react' function HomePage (): JSX.Element { const [members, setMembers] = React.useState([]) + const [error, setError] = useState(null) useEffect(() => { void getAllUsers().then((response) => { setMembers(response.data as User[]) + }).catch((error) => { + console.error(error) + setError('Failed to load Blueprint members. Please try again later.') }) }, []) @@ -18,7 +22,7 @@ function HomePage (): JSX.Element { - + {error ? ({error}) : ()} ) From cad423e6134de7decb25c5b1b2f6a78d77c9fdc9 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Thu, 28 Mar 2024 15:55:34 -0400 Subject: [PATCH 05/24] feat: Added spinner when loading table --- src/pages/HomePage.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index 9c15a47..7f6cad7 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -1,4 +1,4 @@ -import { Container, HStack, Text } from '@chakra-ui/react' +import { Center, Container, HStack, Spinner, Text } from '@chakra-ui/react' import TableDashboard from '../components/TableDashboard' import Sidebar from '../components/Sidebar' import { getAllUsers } from '../api/lib/users' @@ -8,13 +8,16 @@ import React, { useEffect, useState } from 'react' function HomePage (): JSX.Element { const [members, setMembers] = React.useState([]) const [error, setError] = useState(null) + const [isLoading, setIsLoading] = useState(true) useEffect(() => { void getAllUsers().then((response) => { setMembers(response.data as User[]) + setIsLoading(false) }).catch((error) => { console.error(error) setError('Failed to load Blueprint members. Please try again later.') + setIsLoading(false) }) }, []) @@ -22,7 +25,8 @@ function HomePage (): JSX.Element { - {error ? ({error}) : ()} + {error && {error}} + {isLoading ?
: }
) From 0b39b0329b9d7c6be9ed6049da7cbc5de85c3ac1 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Thu, 28 Mar 2024 15:59:31 -0400 Subject: [PATCH 06/24] fix: Changed the positioning of error message --- src/pages/HomePage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index 7f6cad7..534db86 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -25,8 +25,8 @@ function HomePage (): JSX.Element { - {error && {error}} {isLoading ?
: } + {error && {error}}
) From a7f40dcca0be007ac6780716747c3acefe6503bb Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:18:13 -0400 Subject: [PATCH 07/24] feat: Changed user type --- src/types/user.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/types/user.ts b/src/types/user.ts index e7e85ef..bc3612c 100644 --- a/src/types/user.ts +++ b/src/types/user.ts @@ -1,8 +1,11 @@ export interface User { + name: string username: string - password: string email: string - displayName: string - role: string[] - enabled: boolean + password: string + hasBlueprintEmail: boolean + isEnabled: boolean + dateJoined: string + roles: string[] + team: string } From 3287813cfc20cc338bdd0ae2ce5cd51b6e6f08e4 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:21:12 -0400 Subject: [PATCH 08/24] feat: Added id --- src/types/user.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types/user.ts b/src/types/user.ts index bc3612c..759e2e8 100644 --- a/src/types/user.ts +++ b/src/types/user.ts @@ -1,4 +1,5 @@ export interface User { + id: string name: string username: string email: string From 33c95dd058648dea5959cc98ef85aec63013ad87 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:21:22 -0400 Subject: [PATCH 09/24] feat: Added team type --- src/types/team.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/types/team.ts diff --git a/src/types/team.ts b/src/types/team.ts new file mode 100644 index 0000000..cea7827 --- /dev/null +++ b/src/types/team.ts @@ -0,0 +1,9 @@ +export interface Team { + id: string + name: string + members: string[] + teamLead: string + productManager: string + dateCreated: string + teamClass: string +} From c5d5e25b0cd661ff4baabf2b94463cd3f532ca79 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:24:12 -0400 Subject: [PATCH 10/24] feat: Added team import --- src/types/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types/index.ts b/src/types/index.ts index c3a9c65..9e9be7b 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1 +1,2 @@ export * from './user' +export * from './team' From 8490d5e7566a47ca0f16d6e030061e0a7d989560 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:24:47 -0400 Subject: [PATCH 11/24] refactor: Changed class to number --- src/types/team.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/team.ts b/src/types/team.ts index cea7827..399d9fc 100644 --- a/src/types/team.ts +++ b/src/types/team.ts @@ -5,5 +5,5 @@ export interface Team { teamLead: string productManager: string dateCreated: string - teamClass: string + teamClass: number } From 117d7ea0dacadc9b40b997b9dc6b69d6b3502aec Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:25:08 -0400 Subject: [PATCH 12/24] feat: Added event type --- src/types/event.ts | 9 +++++++++ src/types/index.ts | 1 + 2 files changed, 10 insertions(+) create mode 100644 src/types/event.ts diff --git a/src/types/event.ts b/src/types/event.ts new file mode 100644 index 0000000..967aa61 --- /dev/null +++ b/src/types/event.ts @@ -0,0 +1,9 @@ +export interface Event { + id: string + description: string + location: string + budget: number + numberOfAttendees: number + data: string + satisfactionFormsId: string[] +} diff --git a/src/types/index.ts b/src/types/index.ts index 9e9be7b..3aacfbc 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,2 +1,3 @@ export * from './user' export * from './team' +export * from './event' From cfc6a0faa3b24b8ff0558c0e6ccb455115d727d9 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:28:56 -0400 Subject: [PATCH 13/24] feat: Added event form type --- src/types/eventForm.ts | 7 +++++++ src/types/index.ts | 1 + 2 files changed, 8 insertions(+) create mode 100644 src/types/eventForm.ts diff --git a/src/types/eventForm.ts b/src/types/eventForm.ts new file mode 100644 index 0000000..92dcd72 --- /dev/null +++ b/src/types/eventForm.ts @@ -0,0 +1,7 @@ +export interface EventForm { + id: string + name: string + email: string + dateCreated: string + eventId: string +} diff --git a/src/types/index.ts b/src/types/index.ts index 3aacfbc..61e63ad 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,3 +1,4 @@ export * from './user' export * from './team' export * from './event' +export * from './eventForm' From d5784c96f42590cf2be5583512136f4525720f87 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:30:14 -0400 Subject: [PATCH 14/24] feat: Added blog --- src/types/blog.ts | 8 ++++++++ src/types/index.ts | 1 + 2 files changed, 9 insertions(+) create mode 100644 src/types/blog.ts diff --git a/src/types/blog.ts b/src/types/blog.ts new file mode 100644 index 0000000..287c26e --- /dev/null +++ b/src/types/blog.ts @@ -0,0 +1,8 @@ +export interface Blog { + id: string + title: string + datePublished: string + lastModified: string + status: string + pathToMarkdown: string +} diff --git a/src/types/index.ts b/src/types/index.ts index 61e63ad..8e0c2e8 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -2,3 +2,4 @@ export * from './user' export * from './team' export * from './event' export * from './eventForm' +export * from './blog' From 22797f1a258bf103adba102b9088b41850f9d929 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:31:51 -0400 Subject: [PATCH 15/24] feat: Added application form type --- src/types/applicationForm.ts | 10 ++++++++++ src/types/index.ts | 1 + 2 files changed, 11 insertions(+) create mode 100644 src/types/applicationForm.ts diff --git a/src/types/applicationForm.ts b/src/types/applicationForm.ts new file mode 100644 index 0000000..1077518 --- /dev/null +++ b/src/types/applicationForm.ts @@ -0,0 +1,10 @@ +export interface ApplicationForm { + id: string + name: string + graduationYear: number + major: string + timesAppliedPreviously: number + roles: string[] + isAccepted: boolean + satisfactionForm: string +} diff --git a/src/types/index.ts b/src/types/index.ts index 8e0c2e8..6477965 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -3,3 +3,4 @@ export * from './team' export * from './event' export * from './eventForm' export * from './blog' +export * from './applicationForm' From 8469c9ffe8bee21b3c685762e56e002c00e026ce Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:34:39 -0400 Subject: [PATCH 16/24] feat: Added application satisfaction form --- src/types/applicationSatisfcationForm.ts | 6 ++++++ src/types/index.ts | 1 + 2 files changed, 7 insertions(+) create mode 100644 src/types/applicationSatisfcationForm.ts diff --git a/src/types/applicationSatisfcationForm.ts b/src/types/applicationSatisfcationForm.ts new file mode 100644 index 0000000..3c3ab58 --- /dev/null +++ b/src/types/applicationSatisfcationForm.ts @@ -0,0 +1,6 @@ +export interface ApplicationSatisfactionForm { + id: string + applicationFormId: string + rating: number + body: string +} diff --git a/src/types/index.ts b/src/types/index.ts index 6477965..ddcf026 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -4,3 +4,4 @@ export * from './event' export * from './eventForm' export * from './blog' export * from './applicationForm' +export * from './applicationSatisfcationForm' From 9b71566225a45eea989b740dd350af4e1ab5acad Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:38:31 -0400 Subject: [PATCH 17/24] feat: Added budget page --- src/pages/BudgetPage.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/pages/BudgetPage.tsx diff --git a/src/pages/BudgetPage.tsx b/src/pages/BudgetPage.tsx new file mode 100644 index 0000000..4007036 --- /dev/null +++ b/src/pages/BudgetPage.tsx @@ -0,0 +1,8 @@ +function BudgetPage (): JSX.Element { + return ( +
+
+ ) +} + +export default BudgetPage From db76e80141c73c6d1cc0536d2b9f308fc5ef6184 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:39:07 -0400 Subject: [PATCH 18/24] feat: Added applications page --- src/pages/ApplicatiosPage.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/pages/ApplicatiosPage.tsx diff --git a/src/pages/ApplicatiosPage.tsx b/src/pages/ApplicatiosPage.tsx new file mode 100644 index 0000000..cd93b4c --- /dev/null +++ b/src/pages/ApplicatiosPage.tsx @@ -0,0 +1,9 @@ +function ApplicationsPage (): JSX.Element { + return ( +
+

Applications

+
+ ) +} + +export default ApplicationsPage From a726c3764486264eec4d7a6708f71606682e8b5a Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:40:10 -0400 Subject: [PATCH 19/24] feat: Added team page --- src/pages/TeamPage.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/pages/TeamPage.tsx diff --git a/src/pages/TeamPage.tsx b/src/pages/TeamPage.tsx new file mode 100644 index 0000000..2513890 --- /dev/null +++ b/src/pages/TeamPage.tsx @@ -0,0 +1,9 @@ +function TeamPage (): JSX.Element { + return ( +
+

Team

+
+ ) +} + +export default TeamPage From 1cd85f1a517704d9d8f25dc1c09ec3f4d7bd8c08 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:41:12 -0400 Subject: [PATCH 20/24] feat: Deleted dashboard page --- src/app/App.tsx | 2 -- src/pages/DashboardPage.tsx | 8 -------- 2 files changed, 10 deletions(-) delete mode 100644 src/pages/DashboardPage.tsx diff --git a/src/app/App.tsx b/src/app/App.tsx index e3c5afa..f645b12 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1,6 +1,5 @@ import { Routes, Route } from 'react-router-dom' import HomePage from '../pages/HomePage' -import DashboardPage from '../pages/DashboardPage' import BlogPage from '../pages/BlogPage' function App (): JSX.Element { @@ -8,7 +7,6 @@ function App (): JSX.Element {
} /> - } /> } />
diff --git a/src/pages/DashboardPage.tsx b/src/pages/DashboardPage.tsx deleted file mode 100644 index bf4b88e..0000000 --- a/src/pages/DashboardPage.tsx +++ /dev/null @@ -1,8 +0,0 @@ -function DashboardPage (): JSX.Element { - return ( -
-
- ) -} - -export default DashboardPage From 2e41b0a34e48e09b5eab853e22db353182e9cafd Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:44:21 -0400 Subject: [PATCH 21/24] feat: Added routing for pages --- src/app/App.tsx | 6 ++++++ src/pages/TeamPage.tsx | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/app/App.tsx b/src/app/App.tsx index f645b12..9eb1358 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1,6 +1,9 @@ import { Routes, Route } from 'react-router-dom' import HomePage from '../pages/HomePage' import BlogPage from '../pages/BlogPage' +import ApplicationsPage from '../pages/ApplicatiosPage' +import BudgetPage from '../pages/BudgetPage' +import TeamPage from '../pages/TeamPage' function App (): JSX.Element { return ( @@ -8,6 +11,9 @@ function App (): JSX.Element { } /> } /> + } /> + } /> + } /> ) diff --git a/src/pages/TeamPage.tsx b/src/pages/TeamPage.tsx index 2513890..27faae2 100644 --- a/src/pages/TeamPage.tsx +++ b/src/pages/TeamPage.tsx @@ -1,7 +1,10 @@ +import { useParams } from 'react-router-dom' + function TeamPage (): JSX.Element { + const { teamName } = useParams() return (
-

Team

+

Team {teamName}

) } From 246151b5d7b181820b4dba00f31bba0b041b3ad8 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 07:51:09 -0400 Subject: [PATCH 22/24] fix: Changed user properties in tabel --- src/components/TableDashboard.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/TableDashboard.tsx b/src/components/TableDashboard.tsx index 454f03e..394870d 100644 --- a/src/components/TableDashboard.tsx +++ b/src/components/TableDashboard.tsx @@ -17,14 +17,14 @@ function TableDashboard ({ members }: { members: User[] }): JSX.Element {
{members .sort((a: User, b: User) => { - return a.displayName.localeCompare(b.displayName) - }).filter((user: User) => !user.enabled) - .map(({ displayName, email, enabled }: User) => // Add type annotation for User + return a.name.localeCompare(b.name) + }).filter((user: User) => !user.isEnabled) + .map(({ name, email, isEnabled }: User) => // Add type annotation for User - + - + )} From 90a863aff04f29ba62c6b6fbda1e90d4e4dded7b Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 14:17:55 -0400 Subject: [PATCH 23/24] refactor: Refactored User calls --- src/api/apiClient.tsx | 2 +- src/api/lib/users.tsx | 32 ++++++++++---------------------- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/src/api/apiClient.tsx b/src/api/apiClient.tsx index 00060bd..f70709d 100644 --- a/src/api/apiClient.tsx +++ b/src/api/apiClient.tsx @@ -1,7 +1,7 @@ import axios, { type AxiosRequestConfig, type Method, type AxiosResponse } from 'axios' const apiClient = axios.create({ - baseURL: 'https://auth.api.sitblueprint.com/api', + baseURL: 'https://dev.api.sitblueprint.com/api/v1', headers: { Accept: 'application/json', 'Content-type': 'application/json' diff --git a/src/api/lib/users.tsx b/src/api/lib/users.tsx index 9beecd3..46e8632 100644 --- a/src/api/lib/users.tsx +++ b/src/api/lib/users.tsx @@ -2,11 +2,12 @@ import { type AxiosResponse, AxiosError } from 'axios' import request from '../apiClient' import type { User } from '../../types/index' -const API_NAME = 'User Management' +const API_NAME = 'Blueprint Backend API' +const BASE = '/user/' export const getAllUsers = async (): Promise => { try { - const response = await request('GET', '/v1/users/all') + const response = await request('GET', BASE + 'all') return response } catch (error) { if (error instanceof AxiosError) { @@ -17,9 +18,9 @@ export const getAllUsers = async (): Promise => { } } -export const getUser = async (username: string): Promise => { +export const getUser = async (userId: string): Promise => { try { - const response = await request('GET', `/v1/users/user?username=${username}`) + const response = await request('GET', BASE + `user?userId=${userId}`) return response } catch (error) { if (error instanceof AxiosError) { @@ -32,7 +33,7 @@ export const getUser = async (username: string): Promise => { export const addUser = async (user: User): Promise => { try { - const response = await request('POST', '/v1/users/user', JSON.stringify(user)) + const response = await request('POST', BASE + 'user', JSON.stringify(user)) return response } catch (error) { if (error instanceof AxiosError) { @@ -43,9 +44,9 @@ export const addUser = async (user: User): Promise => { } } -export const updateUser = async (username: string, user: User): Promise => { +export const updateUser = async (user: User): Promise => { try { - const response = await request('PUT', `/v1/users/user?username=${username}`, JSON.stringify(user)) + const response = await request('PUT', BASE + 'user', JSON.stringify(user)) return response } catch (error) { if (error instanceof AxiosError) { @@ -56,22 +57,9 @@ export const updateUser = async (username: string, user: User): Promise => { +export const deleteUser = async (userId: string): Promise => { try { - const response = await request('DELETE', `/v1/users/user?username=${username}`) - return response - } catch (error) { - if (error instanceof AxiosError) { - console.error(`${API_NAME} Error: ${error.message}`, error.response?.data) - throw new Error(`${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}`) - } - throw new Error('Unknown Error') - } -} - -export const getMemberSizeWeeklyChange = async (): Promise => { - try { - const response = await request('GET', '/v1/users/memberSizeWeeklyChange') + const response = await request('DELETE', BASE + `userId?=${userId}`) return response } catch (error) { if (error instanceof AxiosError) { From 11d7d542b91f1d68d23953b55eba4b5204b0f7d5 Mon Sep 17 00:00:00 2001 From: miguel-merlin Date: Tue, 9 Apr 2024 14:33:43 -0400 Subject: [PATCH 24/24] style: Fixed Styling --- package-lock.json | 18 +++++- package.json | 6 +- src/api/apiClient.tsx | 12 +++- src/api/lib/team.tsx | 36 ++++++++++++ src/api/lib/users.tsx | 45 +++++++++++---- src/app/App.tsx | 10 ++-- src/components/MetricCard.tsx | 7 ++- src/components/Sidebar.tsx | 90 +++++++++++++++++++++++++---- src/components/TableDashboard.tsx | 23 +++++--- src/components/UserCard.tsx | 5 +- src/components/icons/BlogIcon.tsx | 15 ++++- src/components/icons/Dashboard.tsx | 15 ++++- src/components/icons/ExpandIcon.tsx | 15 ++++- src/components/icons/HomeIcon.tsx | 15 ++++- src/index.tsx | 6 +- src/pages/BlogPage.tsx | 5 +- src/pages/BudgetPage.tsx | 5 +- src/pages/HomePage.tsx | 31 ++++++---- src/sample_data.json | 37 +++++------- 19 files changed, 298 insertions(+), 98 deletions(-) create mode 100644 src/api/lib/team.tsx diff --git a/package-lock.json b/package-lock.json index 8dd2e64..73ddab5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,7 +36,8 @@ "eslint-plugin-import": "^2.29.1", "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^6.1.1", - "eslint-plugin-react": "^7.33.2" + "eslint-plugin-react": "^7.33.2", + "prettier": "^3.2.5" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -16307,6 +16308,21 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", diff --git a/package.json b/package.json index f66c0b6..46c3a3d 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,8 @@ "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", - "lint": "eslint \"src/**/*.{js,jsx,tsx,ts}\" --fix" + "lint": "eslint \"src/**/*.{js,jsx,tsx,ts}\" --fix", + "format": "prettier --write \"src/**/*.{js,jsx,tsx,ts,json,css,scss,md}\"" }, "eslintConfig": { "extends": [ @@ -56,6 +57,7 @@ "eslint-plugin-import": "^2.29.1", "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^6.1.1", - "eslint-plugin-react": "^7.33.2" + "eslint-plugin-react": "^7.33.2", + "prettier": "^3.2.5" } } diff --git a/src/api/apiClient.tsx b/src/api/apiClient.tsx index f70709d..47a6dd5 100644 --- a/src/api/apiClient.tsx +++ b/src/api/apiClient.tsx @@ -1,4 +1,8 @@ -import axios, { type AxiosRequestConfig, type Method, type AxiosResponse } from 'axios' +import axios, { + type AxiosRequestConfig, + type Method, + type AxiosResponse +} from 'axios' const apiClient = axios.create({ baseURL: 'https://dev.api.sitblueprint.com/api/v1', @@ -8,7 +12,11 @@ const apiClient = axios.create({ } } satisfies AxiosRequestConfig) -const request = async (method: Method, url: string, params?: unknown): Promise => { +const request = async ( + method: Method, + url: string, + params?: unknown +): Promise => { return await apiClient.request({ method, url, params }) } diff --git a/src/api/lib/team.tsx b/src/api/lib/team.tsx new file mode 100644 index 0000000..e6785a8 --- /dev/null +++ b/src/api/lib/team.tsx @@ -0,0 +1,36 @@ +import { type AxiosResponse, AxiosError } from 'axios' +import request from '../apiClient' + +const API_NAME = 'Blueprint Backend API' +const BASE = '/team/' + +export const getAllTeams = async (): Promise => { + try { + const response = await request('GET', BASE + 'all') + return response + } catch (error) { + if (error instanceof AxiosError) { + console.error(`${API_NAME} Error: ${error.message}`, error.response?.data) + throw new Error(`${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}`) + } + throw new Error('Unknown Error') + } +} + +export const getTeam = async (teamId: string): Promise => { + try { + const response = await request('GET', BASE + `user?userId=${teamId}`) + return response + } catch (error) { + if (error instanceof AxiosError) { + console.error( + `${API_NAME} Error: ${error.message}`, + error.response?.data + ) + throw new Error( + `${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}` + ) + } + throw new Error('Unknown Error') + } +} diff --git a/src/api/lib/users.tsx b/src/api/lib/users.tsx index 46e8632..6f79505 100644 --- a/src/api/lib/users.tsx +++ b/src/api/lib/users.tsx @@ -11,8 +11,13 @@ export const getAllUsers = async (): Promise => { return response } catch (error) { if (error instanceof AxiosError) { - console.error(`${API_NAME} Error: ${error.message}`, error.response?.data) - throw new Error(`${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}`) + console.error( + `${API_NAME} Error: ${error.message}`, + error.response?.data + ) + throw new Error( + `${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}` + ) } throw new Error('Unknown Error') } @@ -24,8 +29,13 @@ export const getUser = async (userId: string): Promise => { return response } catch (error) { if (error instanceof AxiosError) { - console.error(`${API_NAME} Error: ${error.message}`, error.response?.data) - throw new Error(`${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}`) + console.error( + `${API_NAME} Error: ${error.message}`, + error.response?.data + ) + throw new Error( + `${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}` + ) } throw new Error('Unknown Error') } @@ -37,8 +47,13 @@ export const addUser = async (user: User): Promise => { return response } catch (error) { if (error instanceof AxiosError) { - console.error(`${API_NAME} Error: ${error.message}`, error.response?.data) - throw new Error(`${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}`) + console.error( + `${API_NAME} Error: ${error.message}`, + error.response?.data + ) + throw new Error( + `${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}` + ) } throw new Error('Unknown Error') } @@ -50,8 +65,13 @@ export const updateUser = async (user: User): Promise => { return response } catch (error) { if (error instanceof AxiosError) { - console.error(`${API_NAME} Error: ${error.message}`, error.response?.data) - throw new Error(`${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}`) + console.error( + `${API_NAME} Error: ${error.message}`, + error.response?.data + ) + throw new Error( + `${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}` + ) } throw new Error('Unknown Error') } @@ -63,8 +83,13 @@ export const deleteUser = async (userId: string): Promise => { return response } catch (error) { if (error instanceof AxiosError) { - console.error(`${API_NAME} Error: ${error.message}`, error.response?.data) - throw new Error(`${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}`) + console.error( + `${API_NAME} Error: ${error.message}`, + error.response?.data + ) + throw new Error( + `${API_NAME} Error: ${error.response?.status} ${error.response?.data?.error}` + ) } throw new Error('Unknown Error') } diff --git a/src/app/App.tsx b/src/app/App.tsx index 9eb1358..6b69adb 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -9,11 +9,11 @@ function App (): JSX.Element { return (
- } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } />
) diff --git a/src/components/MetricCard.tsx b/src/components/MetricCard.tsx index c342015..8db2323 100644 --- a/src/components/MetricCard.tsx +++ b/src/components/MetricCard.tsx @@ -13,7 +13,12 @@ interface MetricCardProps { change: 'increase' | 'decrease' } -function MetricCard ({ label, statistic, changePercentage, change }: MetricCardProps): JSX.Element { +function MetricCard ({ + label, + statistic, + changePercentage, + change +}: MetricCardProps): JSX.Element { return ( {label} diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index ad51ad2..267a2db 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -1,6 +1,15 @@ import { useState } from 'react' import { Link as ReactRouterLink } from 'react-router-dom' -import { Box, Flex, HStack, VStack, Button, Image, Text, Link as ChakraLink } from '@chakra-ui/react' +import { + Box, + Flex, + HStack, + VStack, + Button, + Image, + Text, + Link as ChakraLink +} from '@chakra-ui/react' import { motion } from 'framer-motion' import HomeIcon from './icons/HomeIcon' import DashboardIcon from './icons/Dashboard' @@ -18,24 +27,75 @@ function Sidebar (): JSX.Element { animate={{ width: hidden ? 0 : '300px' }} transition={{ ease: 'easeOut', duration: 0.3 }} > - + - + - - - - - - @@ -43,7 +103,17 @@ function Sidebar (): JSX.Element { - + ) } diff --git a/src/components/TableDashboard.tsx b/src/components/TableDashboard.tsx index 394870d..7c7509d 100644 --- a/src/components/TableDashboard.tsx +++ b/src/components/TableDashboard.tsx @@ -5,7 +5,7 @@ import React from 'react' function TableDashboard ({ members }: { members: User[] }): JSX.Element { return ( -
{displayName} {email}
{displayName}{name} {email} {enabled ? 'Inactive' : 'Active'}{isEnabled ? 'Active' : 'Inactive'}
+
@@ -18,14 +18,19 @@ function TableDashboard ({ members }: { members: User[] }): JSX.Element { {members .sort((a: User, b: User) => { return a.name.localeCompare(b.name) - }).filter((user: User) => !user.isEnabled) - .map(({ name, email, isEnabled }: User) => // Add type annotation for User - - - - - - + }) + .filter((user: User) => !user.isEnabled) + .map( + ( + { name, email, isEnabled }: User // Add type annotation for User + ) => ( + + + + + + + ) )}
Name
{name}{email}{isEnabled ? 'Active' : 'Inactive'}
{name}{email}{isEnabled ? 'Active' : 'Inactive'}
diff --git a/src/components/UserCard.tsx b/src/components/UserCard.tsx index 3737f6f..6442606 100644 --- a/src/components/UserCard.tsx +++ b/src/components/UserCard.tsx @@ -1,8 +1,5 @@ function UserCard (): JSX.Element { - return ( -
-
- ) + return
} export default UserCard diff --git a/src/components/icons/BlogIcon.tsx b/src/components/icons/BlogIcon.tsx index 815fb83..b54647e 100644 --- a/src/components/icons/BlogIcon.tsx +++ b/src/components/icons/BlogIcon.tsx @@ -2,10 +2,19 @@ import { Icon } from '@chakra-ui/react' function BlogIcon (): JSX.Element { return ( - - + + ) -}; +} export default BlogIcon diff --git a/src/components/icons/Dashboard.tsx b/src/components/icons/Dashboard.tsx index c6e4504..f6dbf23 100644 --- a/src/components/icons/Dashboard.tsx +++ b/src/components/icons/Dashboard.tsx @@ -2,10 +2,19 @@ import { Icon } from '@chakra-ui/react' function DashboardIcon (): JSX.Element { return ( - - + + ) -}; +} export default DashboardIcon diff --git a/src/components/icons/ExpandIcon.tsx b/src/components/icons/ExpandIcon.tsx index 40885ff..9f4e886 100644 --- a/src/components/icons/ExpandIcon.tsx +++ b/src/components/icons/ExpandIcon.tsx @@ -2,10 +2,19 @@ import { Icon } from '@chakra-ui/react' function ExpandIcon (): JSX.Element { return ( - - + + ) -}; +} export default ExpandIcon diff --git a/src/components/icons/HomeIcon.tsx b/src/components/icons/HomeIcon.tsx index 991fef8..b63aeb0 100644 --- a/src/components/icons/HomeIcon.tsx +++ b/src/components/icons/HomeIcon.tsx @@ -2,10 +2,19 @@ import { Icon } from '@chakra-ui/react' function HomeIcon (): JSX.Element { return ( - - + + ) -}; +} export default HomeIcon diff --git a/src/index.tsx b/src/index.tsx index 5dc11df..a65ba5c 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -12,9 +12,9 @@ if (rootElement !== null) { root.render( - - - + + + ) diff --git a/src/pages/BlogPage.tsx b/src/pages/BlogPage.tsx index 6905fe9..9aa33da 100644 --- a/src/pages/BlogPage.tsx +++ b/src/pages/BlogPage.tsx @@ -1,8 +1,5 @@ function BlogPage (): JSX.Element { - return ( -
-
- ) + return
} export default BlogPage diff --git a/src/pages/BudgetPage.tsx b/src/pages/BudgetPage.tsx index 4007036..a589c3f 100644 --- a/src/pages/BudgetPage.tsx +++ b/src/pages/BudgetPage.tsx @@ -1,8 +1,5 @@ function BudgetPage (): JSX.Element { - return ( -
-
- ) + return
} export default BudgetPage diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index 534db86..cd5c706 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -11,22 +11,33 @@ function HomePage (): JSX.Element { const [isLoading, setIsLoading] = useState(true) useEffect(() => { - void getAllUsers().then((response) => { - setMembers(response.data as User[]) - setIsLoading(false) - }).catch((error) => { - console.error(error) - setError('Failed to load Blueprint members. Please try again later.') - setIsLoading(false) - }) + void getAllUsers() + .then((response) => { + setMembers(response.data as User[]) + setIsLoading(false) + }) + .catch((error) => { + console.error(error) + setError('Failed to load Blueprint members. Please try again later.') + setIsLoading(false) + }) }, []) return ( - {isLoading ?
: } - {error && {error}} + {isLoading + ? ( +
+ {' '} + {' '} +
+ ) + : ( + + )} + {error && {error}}
) diff --git a/src/sample_data.json b/src/sample_data.json index bf0f783..0cac56b 100644 --- a/src/sample_data.json +++ b/src/sample_data.json @@ -1,23 +1,18 @@ { - "Users": { - "user1": { - "Disabled": false, - "Displayname": "Blueprint User 1", - "Password": "existingpassword", - "Email": "user1@blueprint.com", - "Groups": [ - "admin", - "dev" - ] - }, - "user2": { - "Disabled": true, - "Displayname": "Blueprint User 2", - "Password": "existingpassword", - "Email": "user2@blueprint.com", - "Groups": [ - "admin" - ] - } + "Users": { + "user1": { + "Disabled": false, + "Displayname": "Blueprint User 1", + "Password": "existingpassword", + "Email": "user1@blueprint.com", + "Groups": ["admin", "dev"] + }, + "user2": { + "Disabled": true, + "Displayname": "Blueprint User 2", + "Password": "existingpassword", + "Email": "user2@blueprint.com", + "Groups": ["admin"] } -} \ No newline at end of file + } +}