fix architecture and write new tests
This commit is contained in:
@@ -34,6 +34,46 @@ export interface InvitePayload {
|
||||
role: 'MANAGER' | 'AGENT'
|
||||
}
|
||||
|
||||
|
||||
export function appendInvitedMember(members: TeamMember[], employee: TeamMember): TeamMember[] {
|
||||
return [...members, employee]
|
||||
}
|
||||
|
||||
export function incrementInvitedStats(stats: TeamStats): TeamStats {
|
||||
return { ...stats, total: stats.total + 1, pending: stats.pending + 1 }
|
||||
}
|
||||
|
||||
export function applyMemberRoleUpdate(members: TeamMember[], memberId: string, role: 'MANAGER' | 'AGENT'): TeamMember[] {
|
||||
return members.map((member) => (member.id === memberId ? { ...member, role } : member))
|
||||
}
|
||||
|
||||
export function applyMemberActivation(members: TeamMember[], memberId: string, isActive: boolean): TeamMember[] {
|
||||
return members.map((member) => (member.id === memberId ? { ...member, isActive } : member))
|
||||
}
|
||||
|
||||
export function applyActivationStats(stats: TeamStats, direction: 'deactivate' | 'reactivate'): TeamStats {
|
||||
return direction === 'deactivate'
|
||||
? { ...stats, active: stats.active - 1, inactive: stats.inactive + 1 }
|
||||
: { ...stats, active: stats.active + 1, inactive: stats.inactive - 1 }
|
||||
}
|
||||
|
||||
export function removeTeamMemberState(members: TeamMember[], stats: TeamStats, memberId: string): { members: TeamMember[]; stats: TeamStats } {
|
||||
const target = members.find((member) => member.id === memberId)
|
||||
|
||||
return {
|
||||
members: members.filter((member) => member.id !== memberId),
|
||||
stats: {
|
||||
...stats,
|
||||
total: stats.total - (target ? 1 : 0),
|
||||
active: target?.isActive ? stats.active - 1 : stats.active,
|
||||
pending: target?.invitationStatus === 'pending' ? stats.pending - 1 : stats.pending,
|
||||
inactive: !target?.isActive && target?.invitationStatus === 'accepted'
|
||||
? stats.inactive - 1
|
||||
: stats.inactive,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export function useTeam() {
|
||||
const [members, setMembers] = useState<TeamMember[]>([])
|
||||
const [stats, setStats] = useState<TeamStats>({ total: 0, active: 0, pending: 0, inactive: 0 })
|
||||
@@ -64,12 +104,8 @@ export function useTeam() {
|
||||
'/team/invite',
|
||||
{ method: 'POST', body: JSON.stringify(payload) }
|
||||
)
|
||||
setMembers((prev) => [...prev, result.employee])
|
||||
setStats((prev) => ({
|
||||
...prev,
|
||||
total: prev.total + 1,
|
||||
pending: prev.pending + 1,
|
||||
}))
|
||||
setMembers((prev) => appendInvitedMember(prev, result.employee))
|
||||
setStats(incrementInvitedStats)
|
||||
return result
|
||||
}, [])
|
||||
|
||||
@@ -78,9 +114,7 @@ export function useTeam() {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({ role }),
|
||||
})
|
||||
setMembers((prev) =>
|
||||
prev.map((m) => (m.id === memberId ? { ...m, role: updated.role } : m))
|
||||
)
|
||||
setMembers((prev) => applyMemberRoleUpdate(prev, memberId, updated.role as 'MANAGER' | 'AGENT'))
|
||||
return updated
|
||||
}, [])
|
||||
|
||||
@@ -88,10 +122,8 @@ export function useTeam() {
|
||||
const updated = await apiFetch<TeamMember>(`/team/${memberId}/deactivate`, {
|
||||
method: 'POST',
|
||||
})
|
||||
setMembers((prev) =>
|
||||
prev.map((m) => (m.id === memberId ? { ...m, isActive: false } : m))
|
||||
)
|
||||
setStats((prev) => ({ ...prev, active: prev.active - 1, inactive: prev.inactive + 1 }))
|
||||
setMembers((prev) => applyMemberActivation(prev, memberId, false))
|
||||
setStats((prev) => applyActivationStats(prev, 'deactivate'))
|
||||
return updated
|
||||
}, [])
|
||||
|
||||
@@ -99,10 +131,8 @@ export function useTeam() {
|
||||
const updated = await apiFetch<TeamMember>(`/team/${memberId}/reactivate`, {
|
||||
method: 'POST',
|
||||
})
|
||||
setMembers((prev) =>
|
||||
prev.map((m) => (m.id === memberId ? { ...m, isActive: true } : m))
|
||||
)
|
||||
setStats((prev) => ({ ...prev, active: prev.active + 1, inactive: prev.inactive - 1 }))
|
||||
setMembers((prev) => applyMemberActivation(prev, memberId, true))
|
||||
setStats((prev) => applyActivationStats(prev, 'reactivate'))
|
||||
return updated
|
||||
}, [])
|
||||
|
||||
@@ -110,18 +140,10 @@ export function useTeam() {
|
||||
await apiFetch<{ success: boolean }>(`/team/${memberId}`, {
|
||||
method: 'DELETE',
|
||||
})
|
||||
const target = members.find((m) => m.id === memberId)
|
||||
setMembers((prev) => prev.filter((m) => m.id !== memberId))
|
||||
setStats((prev) => ({
|
||||
...prev,
|
||||
total: prev.total - 1,
|
||||
active: target?.isActive ? prev.active - 1 : prev.active,
|
||||
pending: target?.invitationStatus === 'pending' ? prev.pending - 1 : prev.pending,
|
||||
inactive: !target?.isActive && target?.invitationStatus === 'accepted'
|
||||
? prev.inactive - 1
|
||||
: prev.inactive,
|
||||
}))
|
||||
}, [members])
|
||||
const nextState = removeTeamMemberState(members, stats, memberId)
|
||||
setMembers(nextState.members)
|
||||
setStats(nextState.stats)
|
||||
}, [members, stats])
|
||||
|
||||
return {
|
||||
members,
|
||||
|
||||
Reference in New Issue
Block a user