Skip to content
This repository has been archived by the owner on Mar 23, 2024. It is now read-only.

Commit

Permalink
Merge pull request #39 from exortme1ster/feature/teams-
Browse files Browse the repository at this point in the history
This PR includes several improvements to teams as well as main page
  • Loading branch information
nmashchenko committed Jun 22, 2023
2 parents e7b17b4 + 92c65ea commit 0a23e73
Show file tree
Hide file tree
Showing 215 changed files with 8,866 additions and 2,068 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/github-actions-demo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: 🪖 Creating .dev.env for nodemailer
- name: 🪖 Creating .dev.env for nodemailer/aws
working-directory: ./server
run: |
touch .dev.env
Expand All @@ -26,6 +26,9 @@ jobs:
echo SMTP_USER=${{ secrets.SMTP_USER }} >> .dev.env
echo SMTP_PASS=${{ secrets.SMTP_PASS }} >> .dev.env
echo SMTP_PORT=${{ secrets.SMTP_PORT }} >> .dev.env
echo AWS_ACCESS_KEY=${{ secrets.AWS_ACCESS_KEY }} >> .dev.env
echo AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }} >> .dev.env
echo AWS_S3_REGION=${{ secrets.AWS_S3_REGION }} >> .dev.env
cat .dev.env
- name: 🎧 Install modules
working-directory: ./server
Expand Down
1 change: 0 additions & 1 deletion client/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Expand Down
4 changes: 2 additions & 2 deletions client/src/api/hooks/auth/useEditUserDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ export const useEditUserDetails = (successHandler) => {

return useMutation(finishRegistration, {
mutationKey: 'finishRegistration',
onSuccess: () => {
onSuccess: async (data) => {
await queryClient.invalidateQueries('checkAuth', { refetchInactive: true })
successHandler()
queryClient.invalidateQueries('checkAuth', { refetchInactive: true })
},
onError: (error) => {
// set error message
Expand Down
9 changes: 6 additions & 3 deletions client/src/api/hooks/auth/useUpdateAvatar.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ export const useUpdateAvatar = (type) => {

return useMutation(updateUserAvatar, {
mutationKey: 'updateUserAvatar',
onSuccess: () => {
queryClient.invalidateQueries('checkAuth', { refetchInactive: true })
onSuccess: async () => {
if (type === 'teams') {
await queryClient.invalidateQueries('getTeamById', { refetchInactive: true })
}

await queryClient.invalidateQueries('checkAuth', { refetchInactive: true })
},
onError: (error) => {
console.log(error)
// set error message
errorToaster(error)
},
Expand Down
22 changes: 2 additions & 20 deletions client/src/api/hooks/team/useCreateTeam.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
import { useMutation, useQueryClient } from 'react-query'
import { useDispatch } from 'react-redux'
import { useNavigate } from 'react-router-dom'
import { useMutation } from 'react-query'

import http from '../../../http'
import { setIsFinishRegistrationStarted, setStep } from '../../../store/reducers/RegistrationAuth'
import { useUpdateAvatar } from '../auth/useUpdateAvatar'

const { api } = http

export const useCreateTeam = (teamAvatar) => {
const queryClient = useQueryClient()
const { mutate: updateAvatar } = useUpdateAvatar('teams')
const dispatch = useDispatch()

const navigate = useNavigate()
export const useCreateTeam = () => {
const createTeam = async (details) => {
const response = await api.post('/teams/create', details)

Expand All @@ -22,14 +13,5 @@ export const useCreateTeam = (teamAvatar) => {

return useMutation(createTeam, {
mutationKey: 'createTeam',
onSuccess: async (data) => {
if (teamAvatar) {
updateAvatar({ teamID: data._id, image: teamAvatar.split(',')[1] })
}
await queryClient.invalidateQueries('checkAuth', { refetchInactive: true })
dispatch(setIsFinishRegistrationStarted(false))
dispatch(setStep(1))
navigate(`/team/${data._id}`)
},
})
}
6 changes: 5 additions & 1 deletion client/src/api/hooks/team/useDelete.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useMutation, useQueryClient } from 'react-query'
import { useNavigate } from 'react-router-dom'

import http from '../../../http'
import { errorToaster } from '../../../shared/components/Toasters/Error.toaster'

const { api } = http

Expand All @@ -18,7 +19,10 @@ export const useDelete = () => {
mutationKey: 'deleteTeam',
onSuccess: () => {
queryClient.invalidateQueries('checkAuth', { refetchInactive: true })
navigate('/team')
navigate('/teams')
},
onError: (error) => {
errorToaster(error)
},
})
}
2 changes: 0 additions & 2 deletions client/src/api/hooks/team/useGetByTag.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import { successToaster } from '../../../shared/components/Toasters/Success.toas
const { api } = http

export const useGetByTag = () => {
const queryClient = useQueryClient()

const getTeamByTag = async (tag) => {
return await api.get(`/teams/tag/${tag}`)
}
Expand Down
18 changes: 10 additions & 8 deletions client/src/api/hooks/team/useGetTeamData.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@ const { api } = http

export const useGetTeamData = (teamId) => {
const getTeamById = async () => {
const response = await api.get(`/teams/${teamId}`)
if (teamId) {
const response = await api.get(`/teams/${teamId}`)

return response.data
return response.data
}
}

const { data, isLoading: isTeamLoading } = useQuery(['getTeamById', teamId], getTeamById, {
refetchOnMount: false,
refetchOnWindowFocus: false,
enabled: !!teamId,
})
const {
data,
isLoading: isTeamLoading,
error,
} = useQuery(['getTeamById', teamId], getTeamById, { retry: 0 })

return { data, isLoading: isTeamLoading }
return { data, isLoading: isTeamLoading, error }
}
22 changes: 15 additions & 7 deletions client/src/api/hooks/team/useInviteUser.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
import { useMutation, useQueryClient } from 'react-query'

import http from '../../../http'
import { errorToaster } from '../../../shared/components/Toasters/Error.toaster'
import { successToaster } from '../../../shared/components/Toasters/Success.toaster'

const { api } = http

export const useInviteUser = (successHandler) => {
export const useInviteUser = () => {
const queryClient = useQueryClient()

const inviteUser = async (details) => {
const { email, teamId, userId } = details
const { email, teamid, from_user_id } = details

console.log(details)

const response = await api.post('/teams/invite', {
email,
teamid: teamId,
from_user_id: userId,
teamid: teamid,
from_user_id: from_user_id,
})
}

return useMutation(inviteUser, {
mutationKey: 'inviteUser',
onSuccess: async () => {
successHandler()
await queryClient.invalidateQueries('checkAuth', { refetchInactive: true })
onSuccess: () => {
successToaster('User was successfully invited.')
queryClient.invalidateQueries('checkAuth', { refetchInactive: true })
},
onError: (error) => {
errorToaster(error)
},
})
}
30 changes: 30 additions & 0 deletions client/src/api/hooks/team/useJoinTeam.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useMutation, useQueryClient } from 'react-query'
import { useNavigate } from 'react-router-dom'

import http from '../../../http'
import { errorToaster } from '../../../shared/components/Toasters/Error.toaster'

const { api } = http

export const useJoinTeam = () => {
const queryClient = useQueryClient()
const navigate = useNavigate()

const joinTeam = async (details) => {
const response = await api.put('/teams/join', details)

return response.data
}

return useMutation(joinTeam, {
mutationKey: 'joinTeam',
onSuccess: async (data) => {
await queryClient.invalidateQueries('checkAuth', { refetchInactive: true })
await queryClient.invalidateQueries('getTeamById', { refetchInactive: true })
navigate(`/team/${data._id}`)
},
onError: (error) => {
errorToaster(error)
},
})
}
41 changes: 41 additions & 0 deletions client/src/api/hooks/team/useLeaveAndJoin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useMutation, useQueryClient } from 'react-query'
import { useNavigate } from 'react-router-dom'

import { errorToaster } from '../../../shared/components/Toasters/Error.toaster'

import { useJoinTeam } from './useJoinTeam'
import { useLeave } from './useLeaveTeam'

export const useLeaveAndJoin = () => {
const queryClient = useQueryClient()
const navigate = useNavigate()
const joinTeamMutation = useJoinTeam()
const leaveTeamMutation = useLeave()

const leaveAndJoin = async (details) => {
await leaveTeamMutation.mutateAsync(details.leaveDetails)

const joinResult = await joinTeamMutation.mutateAsync(details.joinDetails)

return joinResult
}

const onSuccess = async (joinDetails) => {
queryClient.invalidateQueries('checkAuth', { refetchInactive: true })
navigate(`/team/${joinDetails._id}`)
}

const leaveAndJoinMutation = useMutation(leaveAndJoin, {
mutationKey: 'leaveAndJoin',
onSuccess,
onError: (error) => {
errorToaster(error)
},
})

return {
leaveAndJoin: leaveAndJoinMutation,
isLeaving: leaveTeamMutation.isLoading,
isJoining: joinTeamMutation.isLoading,
}
}
29 changes: 29 additions & 0 deletions client/src/api/hooks/team/useLeaveTeam.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useMutation, useQueryClient } from 'react-query'
import { useNavigate } from 'react-router-dom'

import http from '../../../http'
import { errorToaster } from '../../../shared/components/Toasters/Error.toaster'

const { api } = http

export const useLeave = () => {
const queryClient = useQueryClient()
const navigate = useNavigate()

const leaveTeam = async (details) => {
const response = await api.put(`/teams/leave`, details)

return response.data
}

return useMutation(leaveTeam, {
mutationKey: 'leaveTeam',
onSuccess: () => {
queryClient.invalidateQueries('checkAuth')
navigate(`/teams`)
},
onError: (error) => {
errorToaster(error)
},
})
}
69 changes: 69 additions & 0 deletions client/src/api/hooks/team/useLoadTeams.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { useEffect, useState } from 'react'
import { useInfiniteQuery } from 'react-query'
import { useSelector } from 'react-redux'
import qs from 'qs'
import uuid from 'uuidv4'

import http from '../../../http'
import checkEntriesForValue from '../../../utils/checkEntriesForValue'
import filteredQueryMaker from '../../../utils/filteredQueryMaker'
import { normalizeFilters } from '../../../utils/normalizeFilters'

const { api } = http

export const useLoadTeams = () => {
const [filtered, setFiltered] = useState(false)
const filters = useSelector((state) => state.teamsFilters)

const normalizedFilters = normalizeFilters(filters)
const [id, setId] = useState()

useEffect(() => {
if (checkEntriesForValue(filters)) {
setFiltered(true)
setId(uuid())
} else {
setFiltered(false)
}
}, [filters])

const getTeams = async ({ pageParam = 1 }) => {
const response = await api.get('/teams', { params: { page: pageParam } })

return response.data
}

const getTeamsFiltered = async ({ pageParam = 1 }) => {
const filtersQuery = filteredQueryMaker.teams(
normalizedFilters.countries,
normalizedFilters.people,
normalizedFilters.name,
normalizedFilters.tag,
)

let queryString = qs.stringify(filtersQuery)
const response = await api.get('/teams/filtered', {
params: { page: pageParam, filtersQuery: queryString },
})

return response.data
}

const query = useInfiniteQuery(
[filtered ? 'teamsFiltered' : 'teams', id],
filtered ? getTeamsFiltered : getTeams,
{
getNextPageParam: (lastPage, allPages) => {
return Math.ceil(lastPage.total / lastPage.limit) !== allPages.length
? allPages.length + 1
: undefined
},
refetchOnWindowFocus: false,
},
)

return {
...query,
filtered,
}
}
28 changes: 28 additions & 0 deletions client/src/api/hooks/team/useRemoveMember.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useMutation, useQueryClient } from 'react-query'
import { useNavigate } from 'react-router-dom'

import http from '../../../http'
import { errorToaster } from '../../../shared/components/Toasters/Error.toaster'

const { api } = http

// refetch data

export const useRemoveMember = () => {
const queryClient = useQueryClient()
const removeMember = async (details) => {
const response = await api.put(`/teams/remove-member`, details)

return response.data
}

return useMutation(removeMember, {
mutationKey: 'removeMember',
onSuccess: async () => {
await queryClient.invalidateQueries('getTeamById') // useQuery key
},
onError: (error) => {
errorToaster(error)
},
})
}
Loading

0 comments on commit 0a23e73

Please sign in to comment.