2022-06-22 16:35:50 +00:00
|
|
|
import {
|
|
|
|
deleteDoc,
|
|
|
|
doc,
|
2022-06-29 19:21:40 +00:00
|
|
|
getDocs,
|
2022-06-22 16:35:50 +00:00
|
|
|
query,
|
|
|
|
updateDoc,
|
|
|
|
where,
|
|
|
|
} from 'firebase/firestore'
|
2022-07-01 13:47:19 +00:00
|
|
|
import { sortBy, uniq } from 'lodash'
|
2022-06-22 16:35:50 +00:00
|
|
|
import { Group } from 'common/group'
|
2022-07-14 15:09:12 +00:00
|
|
|
import { updateContract } from './contracts'
|
2022-06-29 19:21:40 +00:00
|
|
|
import {
|
|
|
|
coll,
|
|
|
|
getValue,
|
|
|
|
getValues,
|
|
|
|
listenForValue,
|
|
|
|
listenForValues,
|
|
|
|
} from './utils'
|
2022-07-13 21:11:22 +00:00
|
|
|
import { Contract } from 'common/contract'
|
2022-06-22 16:35:50 +00:00
|
|
|
|
2022-06-29 19:21:40 +00:00
|
|
|
export const groups = coll<Group>('groups')
|
2022-06-22 16:35:50 +00:00
|
|
|
|
|
|
|
export function groupPath(
|
|
|
|
groupSlug: string,
|
2022-07-06 23:24:53 +00:00
|
|
|
subpath?: 'edit' | 'questions' | 'about' | 'chat' | 'rankings'
|
2022-06-22 16:35:50 +00:00
|
|
|
) {
|
|
|
|
return `/group/${groupSlug}${subpath ? `/${subpath}` : ''}`
|
|
|
|
}
|
|
|
|
|
|
|
|
export function updateGroup(group: Group, updates: Partial<Group>) {
|
2022-06-29 19:21:40 +00:00
|
|
|
return updateDoc(doc(groups, group.id), updates)
|
2022-06-22 16:35:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export function deleteGroup(group: Group) {
|
2022-06-29 19:21:40 +00:00
|
|
|
return deleteDoc(doc(groups, group.id))
|
2022-06-22 16:35:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export async function listAllGroups() {
|
2022-06-29 19:21:40 +00:00
|
|
|
return getValues<Group>(groups)
|
2022-06-22 16:35:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export function listenForGroups(setGroups: (groups: Group[]) => void) {
|
2022-06-29 19:21:40 +00:00
|
|
|
return listenForValues(groups, setGroups)
|
2022-06-22 16:35:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export function getGroup(groupId: string) {
|
2022-06-29 19:21:40 +00:00
|
|
|
return getValue<Group>(doc(groups, groupId))
|
2022-06-22 16:35:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export async function getGroupBySlug(slug: string) {
|
2022-06-29 19:21:40 +00:00
|
|
|
const q = query(groups, where('slug', '==', slug))
|
|
|
|
const docs = (await getDocs(q)).docs
|
|
|
|
return docs.length === 0 ? null : docs[0].data()
|
2022-06-22 16:35:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export function listenForGroup(
|
|
|
|
groupId: string,
|
|
|
|
setGroup: (group: Group | null) => void
|
|
|
|
) {
|
2022-06-29 19:21:40 +00:00
|
|
|
return listenForValue(doc(groups, groupId), setGroup)
|
2022-06-22 16:35:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export function listenForMemberGroups(
|
|
|
|
userId: string,
|
|
|
|
setGroups: (groups: Group[]) => void
|
|
|
|
) {
|
2022-06-29 19:21:40 +00:00
|
|
|
const q = query(groups, where('memberIds', 'array-contains', userId))
|
2022-06-22 16:35:50 +00:00
|
|
|
|
|
|
|
return listenForValues<Group>(q, (groups) => {
|
|
|
|
const sorted = sortBy(groups, [(group) => -group.mostRecentActivityTime])
|
|
|
|
setGroups(sorted)
|
|
|
|
})
|
|
|
|
}
|
2022-06-22 22:19:17 +00:00
|
|
|
|
|
|
|
export async function getGroupsWithContractId(
|
|
|
|
contractId: string,
|
|
|
|
setGroups: (groups: Group[]) => void
|
|
|
|
) {
|
2022-06-29 19:21:40 +00:00
|
|
|
const q = query(groups, where('contractIds', 'array-contains', contractId))
|
|
|
|
setGroups(await getValues<Group>(q))
|
2022-06-22 22:19:17 +00:00
|
|
|
}
|
2022-06-29 16:00:43 +00:00
|
|
|
|
2022-07-01 13:47:19 +00:00
|
|
|
export async function addUserToGroupViaSlug(groupSlug: string, userId: string) {
|
|
|
|
// get group to get the member ids
|
|
|
|
const group = await getGroupBySlug(groupSlug)
|
|
|
|
if (!group) {
|
|
|
|
console.error(`Group not found: ${groupSlug}`)
|
|
|
|
return
|
|
|
|
}
|
2022-07-01 22:37:30 +00:00
|
|
|
return await addUserToGroup(group, userId)
|
2022-07-01 13:47:19 +00:00
|
|
|
}
|
|
|
|
|
2022-07-01 22:37:30 +00:00
|
|
|
export async function addUserToGroup(
|
|
|
|
group: Group,
|
|
|
|
userId: string
|
|
|
|
): Promise<Group> {
|
2022-06-29 16:00:43 +00:00
|
|
|
const { memberIds } = group
|
|
|
|
if (memberIds.includes(userId)) {
|
|
|
|
return group
|
|
|
|
}
|
|
|
|
const newMemberIds = [...memberIds, userId]
|
|
|
|
const newGroup = { ...group, memberIds: newMemberIds }
|
2022-07-01 13:47:19 +00:00
|
|
|
await updateGroup(newGroup, { memberIds: uniq(newMemberIds) })
|
2022-06-29 16:00:43 +00:00
|
|
|
return newGroup
|
|
|
|
}
|
2022-07-14 13:53:41 +00:00
|
|
|
|
2022-06-29 16:00:43 +00:00
|
|
|
export async function leaveGroup(group: Group, userId: string): Promise<Group> {
|
|
|
|
const { memberIds } = group
|
|
|
|
if (!memberIds.includes(userId)) {
|
|
|
|
return group
|
|
|
|
}
|
|
|
|
const newMemberIds = memberIds.filter((id) => id !== userId)
|
|
|
|
const newGroup = { ...group, memberIds: newMemberIds }
|
2022-07-01 13:47:19 +00:00
|
|
|
await updateGroup(newGroup, { memberIds: uniq(newMemberIds) })
|
2022-06-29 16:00:43 +00:00
|
|
|
return newGroup
|
|
|
|
}
|
2022-07-01 22:37:30 +00:00
|
|
|
|
2022-07-13 21:11:22 +00:00
|
|
|
export async function addContractToGroup(group: Group, contract: Contract) {
|
|
|
|
await updateContract(contract.id, {
|
|
|
|
groupSlugs: [...(contract.groupSlugs ?? []), group.slug],
|
|
|
|
})
|
|
|
|
return await updateGroup(group, {
|
|
|
|
contractIds: uniq([...group.contractIds, contract.id]),
|
|
|
|
})
|
|
|
|
.then(() => group)
|
|
|
|
.catch((err) => {
|
|
|
|
console.error('error adding contract to group', err)
|
|
|
|
return err
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function setContractGroupSlugs(group: Group, contractId: string) {
|
|
|
|
await updateContract(contractId, { groupSlugs: [group.slug] })
|
2022-07-01 22:37:30 +00:00
|
|
|
return await updateGroup(group, {
|
|
|
|
contractIds: uniq([...group.contractIds, contractId]),
|
|
|
|
})
|
|
|
|
.then(() => group)
|
|
|
|
.catch((err) => {
|
|
|
|
console.error('error adding contract to group', err)
|
|
|
|
return err
|
|
|
|
})
|
|
|
|
}
|