// updating specific user changes other users // for example, updating the status of a corporate user should update the status of all users in the same corporate group import {UserStatus, User} from "../interfaces/user"; import {getFirestore, collection, getDocs, getDoc, doc, setDoc, query, where} from "firebase/firestore"; import {app} from "@/firebase"; const db = getFirestore(app); export const propagateStatusChange = (userId: string, status: UserStatus) => new Promise((resolve, reject) => { getDoc(doc(db, "users", userId)) .then((docUser) => { const user = docUser.data() as User; // only update the status of the user's groups if the user is a corporate user if (user.type === "corporate" || user.type === "mastercorporate") { getDocs(query(collection(db, "groups"), where("admin", "==", userId))).then(async (userGroupsRef) => { const userGroups = userGroupsRef.docs.map((x) => x.data()); const targetUsers = [...new Set(userGroups.flatMap((g) => g.participants).filter((u) => u))]; Promise.all( targetUsers.map(async (targetUserId) => { const ref = await getDoc(doc(db, "users", targetUserId)); if (!ref.exists()) return null; const data = ref.data() as User; return {...data, id: targetUserId}; }), ) .then((data) => { const filtered = data.filter((x) => { if (x === null) return false; if (x.status === status) return false; return true; }) as User[]; if (filtered.length === 0) { return; } Promise.all(filtered.map((user: User) => setDoc(doc(db, "users", user.id), {status}, {merge: true}))) .then(() => { resolve(true); }) .catch((err) => { console.error(err); reject(err); }); }) .catch((err) => { console.error(err); reject(err); }); }); return; } const error = new Error("User is not a corporate user"); console.error(error); reject(error); }) .catch((err) => { console.error(err); reject(err); }); }); export const propagateExpiryDateChanges = (userId: string, initialExpiryDate: Date | null | undefined, subscriptionExpirationDate: Date | null) => new Promise((resolve, reject) => { getDoc(doc(db, "users", userId)) .then((docUser) => { const user = docUser.data() as User; // only update the status of the user's groups if the user is a corporate user if (user.type === "corporate") { getDocs(query(collection(db, "groups"), where("admin", "==", userId))).then(async (userGroupsRef) => { const userGroups = userGroupsRef.docs.map((x) => x.data()); const targetUsers = [...new Set(userGroups.flatMap((g) => g.participants).filter((u) => u))]; Promise.all( targetUsers.map(async (targetUserId) => { const ref = await getDoc(doc(db, "users", targetUserId)); if (!ref.exists()) return null; const data = ref.data() as User; return {...data, id: ref.id}; }), ) .then(async (data) => { const filtered = data.filter((x) => { if (x === null) return false; if (!x.subscriptionExpirationDate && !initialExpiryDate) return true; if (x.subscriptionExpirationDate !== initialExpiryDate) return false; return true; }) as User[]; if (filtered.length === 0) return; for (const user of filtered) { await setDoc(doc(db, "users", user.id), {subscriptionExpirationDate}, {merge: true}); } resolve(true); }) .catch((err) => { console.error(err); reject(err); }); }); return; } const error = new Error("User is not a corporate user"); console.error(error); reject(error); }) .catch((err) => { console.error(err); reject(err); }); });