diff --git a/src/components/Auth/api.ts b/src/components/Auth/api.ts index eb31edc4d..8637abae4 100644 --- a/src/components/Auth/api.ts +++ b/src/components/Auth/api.ts @@ -7,6 +7,7 @@ export enum ApiEndpoints { VERIFY = 'users/verify', RESEND_VERIFICATION = 'users/verify/code', ACCOUNT_CREATE = 'organizations', + TEAM_MEMBERS = 'organizations/{address}/members', } interface IApiError { @@ -44,8 +45,8 @@ export type ApiParams = { } export const api = ( - path: ApiEndpoints, - { body, method = 'GET', headers = new Headers({}) }: ApiParams + path: string, + { body, method = 'GET', headers = new Headers({}) }: ApiParams = {} ): Promise => { headers.append('Content-Type', 'application/json') return fetch(`${import.meta.env.SAAS_URL}${path}`, { diff --git a/src/components/Auth/useAuthProvider.ts b/src/components/Auth/useAuthProvider.ts index a8e74af7e..9db67187d 100644 --- a/src/components/Auth/useAuthProvider.ts +++ b/src/components/Auth/useAuthProvider.ts @@ -62,7 +62,7 @@ export const useAuthProvider = () => { const { mutate: updateSigner, isIdle: signerIdle, isPending: signerPending, data: signerAddress } = useSigner() const bearedFetch = useCallback( - (path: ApiEndpoints, { headers = new Headers({}), ...params }: ApiParams) => { + (path: string, { headers = new Headers({}), ...params }: ApiParams = {}) => { if (!bearer) { logout() throw new Error('No bearer token') diff --git a/src/components/Layout/ErrorComponent.tsx b/src/components/Layout/ErrorComponent.tsx new file mode 100644 index 000000000..48bda49bf --- /dev/null +++ b/src/components/Layout/ErrorComponent.tsx @@ -0,0 +1,28 @@ +import { Flex, FlexProps, Text } from '@chakra-ui/react' +import { WarningIcon } from '@chakra-ui/icons' +import { useTranslation } from 'react-i18next' + +const ErrorComponent = ({ error, ...props }: { error: Error } & FlexProps) => { + const { t } = useTranslation() + + return ( + + + {t('error.loading_page')} + {error.toString()} + + ) +} + +export default ErrorComponent diff --git a/src/components/OrganizationSaas/Dashboard/Team.tsx b/src/components/OrganizationSaas/Dashboard/Team.tsx index 1addeb96e..ad8dd2f29 100644 --- a/src/components/OrganizationSaas/Dashboard/Team.tsx +++ b/src/components/OrganizationSaas/Dashboard/Team.tsx @@ -1,6 +1,121 @@ -import { Button, Flex } from '@chakra-ui/react' +import { + Avatar, + Badge, + Box, + Button, + Flex, + Heading, + Table, + TableContainer, + Tbody, + Td, + Text, + Th, + Thead, + Tr, +} from '@chakra-ui/react' import { useState } from 'react' import Invite from './Invite' +import { useAuth } from '~components/Auth/useAuth' +import { useQuery, UseQueryOptions } from '@tanstack/react-query' +import { ApiEndpoints } from '~components/Auth/api' +import { Loading } from '~src/router/SuspenseLoader' +import ErrorComponent from '~components/Layout/ErrorComponent' +import { Trans, useTranslation } from 'react-i18next' + +type UserInfo = { + email: string + firstName: string + lastName: string +} + +type ITeamMembersResponse = { + members: { + info: UserInfo + role: string + }[] +} + +const useTeamMembers = ({ + options, +}: { + options?: Omit, 'queryKey' | 'queryFn'> +} = {}) => { + const { bearedFetch, signerAddress } = useAuth() + return useQuery({ + queryKey: ['organizations', 'members', signerAddress], + queryFn: () => bearedFetch(ApiEndpoints.TEAM_MEMBERS.replace('{address}', signerAddress)), + ...options, + }) +} + +const TeamList = () => { + const { t } = useTranslation() + const { data, isLoading, isError, error } = useTeamMembers() + + if (isLoading) { + return + } + if (isError) { + return + } + if (!data.members) { + return null + } + + const members = data.members + + return ( + + + Team members + + {members.length} + + + + + + + + + + + + {members.map((member, i) => { + return ( + + + + + ) + })} + +
+ Name + + Permission +
+ + + + + {member.info.firstName} {member.info.lastName} + + {member.info.email} + + + + {member.role} +
+
+
+ ) +} const Team = () => { const [inviteView, setInviteView] = useState(false) @@ -11,6 +126,7 @@ const Team = () => { {!inviteView && } {inviteView && } + ) }