placementt-core 1.20.211 → 11.10.151

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/.eslintrc.js +40 -40
  2. package/.gitattributes +2 -2
  3. package/lib/config.d.ts +0 -1
  4. package/lib/constants.d.ts +6 -2
  5. package/lib/constants.js +136 -136
  6. package/lib/constants.js.map +1 -1
  7. package/lib/features/analytics/useAnalytics.d.ts +0 -1
  8. package/lib/features/analytics/useAnalytics.js +3 -4
  9. package/lib/features/analytics/useAnalytics.js.map +1 -1
  10. package/lib/features/config.d.ts +133 -133
  11. package/lib/features/config.js +35 -35
  12. package/lib/features/contacts/contacts.d.ts +75 -75
  13. package/lib/features/contacts/contacts.js +105 -105
  14. package/lib/features/contacts/contactsSlice.d.ts +5 -5
  15. package/lib/features/contacts/useContacts.js +1 -2
  16. package/lib/features/contacts/useContacts.js.map +1 -1
  17. package/lib/features/downtime/useDowntime.d.ts +11 -11
  18. package/lib/features/downtime/useDowntime.js +22 -22
  19. package/lib/features/dropdown/useDropdown.d.ts +2 -3
  20. package/lib/features/dropdown/useDropdown.js +1 -2
  21. package/lib/features/dropdown/useDropdown.js.map +1 -1
  22. package/lib/features/global/downtime/useDowntime.d.ts +0 -1
  23. package/lib/features/global/downtime/useDowntime.js +1 -2
  24. package/lib/features/global/downtime/useDowntime.js.map +1 -1
  25. package/lib/features/global/users/useUserFunctions.d.ts +0 -1
  26. package/lib/features/global/users/useUserFunctions.js +7 -8
  27. package/lib/features/global/users/useUserFunctions.js.map +1 -1
  28. package/lib/features/placements/studentPlacements/activePlacement.d.ts +1 -1
  29. package/lib/features/placements/studentPlacements/completedStudentPlacementsSlice.d.ts +2 -2
  30. package/lib/features/placements/studentPlacements/studentPlacementsSlice.d.ts +63 -63
  31. package/lib/features/placements/studentPlacements/studentPlacementsSlice.js +81 -81
  32. package/lib/features/placements/studentPlacements/upcomingStudentPlacementsSlice.d.ts +2 -2
  33. package/lib/features/placements/studentPlacements/useStudentPlacements.d.ts +0 -1
  34. package/lib/features/placements/studentPlacements/useStudentPlacements.js +1 -2
  35. package/lib/features/placements/studentPlacements/useStudentPlacements.js.map +1 -1
  36. package/lib/features/providerPlacements/providerPlacementsSlice.d.ts +19 -19
  37. package/lib/features/providerPlacements/providerPlacementsSlice.js +24 -24
  38. package/lib/features/referrals/useReferrals.d.ts +0 -1
  39. package/lib/features/referrals/useReferrals.js +1 -2
  40. package/lib/features/referrals/useReferrals.js.map +1 -1
  41. package/lib/features/studentPlacements/studentPlacementsSlice.d.ts +62 -62
  42. package/lib/features/studentPlacements/studentPlacementsSlice.js +87 -87
  43. package/lib/features/studentPlacements/useStudentPlacements.d.ts +6 -6
  44. package/lib/features/studentPlacements/useStudentPlacements.js +18 -18
  45. package/lib/features/updates/useUpdates.js +1 -2
  46. package/lib/features/updates/useUpdates.js.map +1 -1
  47. package/lib/features/userSlice.d.ts +26 -26
  48. package/lib/features/userSlice.js +23 -23
  49. package/lib/features/users/useUserFunctions.d.ts +25 -25
  50. package/lib/features/users/useUserFunctions.js +124 -124
  51. package/lib/features/users/userSlice.d.ts +46 -46
  52. package/lib/features/users/userSlice.js +48 -48
  53. package/lib/firebase/firebase.d.ts +3 -1
  54. package/lib/firebase/firebase.js +9 -3
  55. package/lib/firebase/firebase.js.map +1 -1
  56. package/lib/firebase/firebaseConfig.js +3 -0
  57. package/lib/firebase/firebaseConfig.js.map +1 -1
  58. package/lib/firebase/firebaseQuery.d.ts +3 -1
  59. package/lib/firebase/firebaseQuery.js +11 -1
  60. package/lib/firebase/firebaseQuery.js.map +1 -1
  61. package/lib/firebase/persistence.js +2 -2
  62. package/lib/firebase/persistence.js.map +1 -1
  63. package/lib/firebase/readDatabase.d.ts +8 -7
  64. package/lib/firebase/readDatabase.js +41 -8
  65. package/lib/firebase/readDatabase.js.map +1 -1
  66. package/lib/firebase/util.d.ts +3 -4
  67. package/lib/firebase/util.js +49 -4
  68. package/lib/firebase/util.js.map +1 -1
  69. package/lib/firebase/writeDatabase.d.ts +7 -3
  70. package/lib/firebase/writeDatabase.js +9 -2
  71. package/lib/firebase/writeDatabase.js.map +1 -1
  72. package/lib/hooks.d.ts +476 -20
  73. package/lib/hooks.js +1855 -237
  74. package/lib/hooks.js.map +1 -1
  75. package/lib/images/GatsbyBenchmarks.d.ts +0 -1
  76. package/lib/images/GatsbyBenchmarks.js +1 -1
  77. package/lib/images/GatsbyBenchmarks.js.map +1 -1
  78. package/lib/reduxHooks.d.ts +9 -2
  79. package/lib/reduxHooks.js +36 -9
  80. package/lib/reduxHooks.js.map +1 -1
  81. package/lib/tasksAndTips.d.ts +25 -5
  82. package/lib/tasksAndTips.js +517 -48
  83. package/lib/tasksAndTips.js.map +1 -1
  84. package/lib/typeDefinitions.d.ts +472 -55
  85. package/lib/util.d.ts +1 -0
  86. package/lib/util.js +85 -7
  87. package/lib/util.js.map +1 -1
  88. package/package.json +52 -49
  89. package/src/DatabaseDefinitions.ts +18 -18
  90. package/src/apiCalls.ts +128 -128
  91. package/src/config.ts +50 -50
  92. package/src/constants.ts +714 -707
  93. package/src/databaseTypes.ts +42 -42
  94. package/src/features/analytics/useAnalytics.tsx +64 -64
  95. package/src/features/contacts/contactsSlice.ts +147 -147
  96. package/src/features/contacts/useContacts.tsx +73 -73
  97. package/src/features/dropdown/useDropdown.tsx +52 -52
  98. package/src/features/global/downtime/useDowntime.tsx +23 -23
  99. package/src/features/global/users/useUserFunctions.tsx +132 -132
  100. package/src/features/jobs/jobsSlice.ts +65 -65
  101. package/src/features/placements/studentPlacements/activePlacement.ts +68 -68
  102. package/src/features/placements/studentPlacements/completedStudentPlacementsSlice.ts +97 -97
  103. package/src/features/placements/studentPlacements/upcomingStudentPlacementsSlice.ts +108 -108
  104. package/src/features/placements/studentPlacements/useStudentPlacements.tsx +9 -9
  105. package/src/features/placements/types.ts +10 -10
  106. package/src/features/referrals/useReferrals.tsx +56 -56
  107. package/src/features/updates/useUpdates.tsx +38 -38
  108. package/src/firebase/firebase.tsx +144 -138
  109. package/src/firebase/firebaseConfig.tsx +45 -42
  110. package/src/firebase/firebaseQuery.tsx +150 -140
  111. package/src/firebase/persistence.ts +84 -84
  112. package/src/firebase/readDatabase.tsx +235 -197
  113. package/src/firebase/util.tsx +352 -308
  114. package/src/firebase/writeDatabase.tsx +77 -68
  115. package/src/hooks.tsx +4029 -1928
  116. package/src/images/GatsbyBenchmarks.tsx +711 -711
  117. package/src/images/LogFuturePlacement.jsx +64 -64
  118. package/src/images/LogPreviousPlacement.jsx +228 -228
  119. package/src/images/gatsby_benchmarks.svg +466 -466
  120. package/src/images/log_future_placement.svg +114 -114
  121. package/src/images/log_previous_placement.svg +199 -199
  122. package/src/index.ts +34 -34
  123. package/src/readDatabase.tsx +3 -3
  124. package/src/reduxHooks.ts +231 -200
  125. package/src/tasksAndTips.ts +917 -410
  126. package/src/tutorialTips.ts +58 -58
  127. package/src/typeDefinitions.ts +893 -503
  128. package/src/util.ts +137 -47
  129. package/tsconfig.dev.json +5 -5
  130. package/tsconfig.json +21 -21
@@ -1,197 +1,235 @@
1
- import {collection, getDocs, limit, orderBy, query, QueryConstraint, where} from "firebase/firestore";
2
- import {getDownloadURL, listAll, ref, StorageReference} from "firebase/storage";
3
- import {SetStateAction} from "react";
4
- import {CohortData, NotificationObject, UserData, UserGroupData} from "../typeDefinitions";
5
- import {db, storage} from "./firebaseConfig";
6
- import FirebaseQuery from "./firebaseQuery";
7
- import {pathToArr, sortByReverseStringLength} from "./util";
8
-
9
- const firebaseQuery = new FirebaseQuery();
10
-
11
- export const getStaffRolesForStudent = async (studentFields:string[], product:string, userObject:UserData) => {
12
- const roleWithStudent = await firebaseQuery.getDocsWhere(
13
- ["staffRoles"],
14
- where("filters.students", "array-contains", userObject.id));
15
-
16
- const roleWithFilters = await studentFields.reduce(async (acc, field) => {
17
- if (!userObject.details[field as keyof typeof userObject]) {
18
- return acc;
19
- }
20
- const roles = await firebaseQuery.getDocsWhere(
21
- ["staffRoles"],
22
- where(`filters.fields.${field}`, "==", userObject.details[field as keyof typeof userObject])) as {[key:string]: unknown};
23
-
24
- if (Object.keys(roles).length > 0) {
25
- acc = {...acc, ...roles};
26
- }
27
- return acc;
28
- }, Promise.resolve({}));
29
-
30
- return {...roleWithFilters, ...roleWithStudent};
31
- };
32
-
33
- export const searchUsers = async (userType:"Staff"|"Students", name:string, user:UserData, lim=5, constraints:QueryConstraint[]=[]) => {
34
- if (name.length < 3) {
35
- return {};
36
- }
37
- // This means we search for the longest string first, thereby probably getting the fewest results.
38
- const sortedNameList = sortByReverseStringLength(name.split(" "));
39
-
40
- const unfilteredUsersByForename = await firebaseQuery.getDocsWhere(
41
- "users",
42
- [where("userType", "==", userType),
43
- where("oId", "==", user.oId),
44
- ...constraints,
45
- where("details.forename", ">=", sortedNameList[0]),
46
- where("details.forename", "<=", sortedNameList[0]+ "\uf8ff"),
47
- limit(lim)]) as {[key:string]: UserData};
48
- const unfilteredUsersBySurname = await firebaseQuery.getDocsWhere(
49
- "users",
50
- [where("userType", "==", userType),
51
- where("oId", "==", user.oId),
52
- ...constraints,
53
- where("details.surname", ">=", sortedNameList[0]),
54
- where("details.surname", "<=", sortedNameList[0]+ "\uf8ff"),
55
- limit(lim)]) as {[key:string]: UserData};
56
-
57
- let userResults = {...unfilteredUsersByForename, ...unfilteredUsersBySurname};
58
- sortedNameList.shift();
59
- sortedNameList.forEach((name) => {
60
- userResults = Object.fromEntries(Object.entries(userResults).filter(([, user]) => user.details.forename.includes(name) || user.details.surname.includes(name)));
61
- });
62
-
63
- return userResults;
64
- };
65
-
66
- type OldUserData = {
67
- userGroup?: string,
68
- cohort?: string,
69
- }
70
-
71
- export const getUser = async (uid: string, setState: SetStateAction<any>) => {
72
- let oldUser:OldUserData = {};
73
- let groupData = {};
74
- let cohortData = {};
75
-
76
- firebaseQuery.documentSnapshot(["users", uid], async (user: UserData) => {
77
- console.log("user", user);
78
- if (user.userGroup && user.userGroup !== "admin") {
79
- // Always set the groupData, but only get it if the user group has changed.keyof
80
- if (oldUser?.userGroup !== user.userGroup) {
81
- groupData = await firebaseQuery.getDocData(["userGroups", user.userGroup]);
82
- }
83
- }
84
- user.groupData = groupData as UserGroupData;
85
-
86
- if (user.cohort) {
87
- // Always set the groupData, but only get it if the user group has changed.keyof
88
- if (oldUser?.cohort !== user.cohort) {
89
- cohortData = await firebaseQuery.getDocData(["cohorts", user.cohort]);
90
- }
91
- }
92
- user.cohortData = cohortData as CohortData;
93
-
94
- oldUser = user;
95
- setState(user)
96
- });
97
- };
98
-
99
- export const getNotifications = async (user: UserData, setState: SetStateAction<any>) => {
100
- const updateNotifications = (notifications:{[key:string]: NotificationObject}, type:"user"|"org") => {
101
- setState((old:{[key:string]: NotificationObject}) => {
102
- const concatenatedNotifications = {
103
- ...old,
104
- ...Object.fromEntries(
105
- Object.entries(notifications)
106
- .map(([k, v]) => [k, {...v, notifType: type}])
107
- ),
108
- };
109
- return Object.fromEntries(Object.entries(concatenatedNotifications).sort(([, a], [, b]) => b.created.toMillis() - a.created.toMillis()));
110
- });
111
- };
112
-
113
- type NotifQuery = [string[], QueryConstraint|QueryConstraint[]];
114
-
115
- const userNotifications:NotifQuery = [["users", user.id, "notifications"], [orderBy("created", "desc"), limit(10)]]; /* , limit(10) */
116
- firebaseQuery.getDocsWhere(userNotifications[0], userNotifications[1]).then((s) => {
117
- updateNotifications(s as {[key:string]: NotificationObject}, "user");
118
- });
119
-
120
- if (user.oId) {
121
- let notificationsQuery:NotifQuery;
122
-
123
- if (user.userGroup === "admin") {
124
- notificationsQuery = [[user.product, user.oId, "notifications"], [orderBy("created", "desc"), limit(10)]]; /* , limit(10) */
125
- } else {
126
- notificationsQuery = [[user.product, user.oId, "notifications"], [where("viewableBy", "array-contains-any", [user.id, user.userGroup]), orderBy("created", "desc")]]; /* , limit(10) */
127
- }
128
- firebaseQuery.getDocsWhere(notificationsQuery[0], notificationsQuery[1]).then((s) => {
129
- updateNotifications(s as {[key:string]: NotificationObject}, "org");
130
- });
131
- }
132
- // Only gets notifications that user can view, either by ID or usergroup. Once user not in group, can no longer see notifications.
133
-
134
- // getCollectionSnapshot(notificationsQuery[0], setState, notificationsQuery[1])
135
- };
136
-
137
-
138
- export const getFiles = async (path: string[]|string) => {
139
- const files = await listAll(ref(storage, ...pathToArr(path)));
140
-
141
- return (await ((Array.from(files.items) as Array<StorageReference>).reduce(async (acc, item) => {
142
- const url = await getDownloadURL(item);
143
- const entry = {name: item.name, url: url};
144
-
145
-
146
- if (!(await acc).includes(entry)) {
147
- (await acc).push(entry);
148
- }
149
- return acc;
150
- }, Promise.resolve([] as Array<{name: string, url: string}>))));
151
- };
152
-
153
-
154
- export const getFormsFromId = async (path: string[]|string, forms: string[]) => {
155
- return (await (Array.from(forms).reduce(async (acc: {[k: string]: any}, item: string) => {
156
- const formData = typeof item === "object" ? item : await firebaseQuery.getDocData([...pathToArr(path), item]);
157
- console.log("formData", formData);
158
-
159
- acc.then((acc: {[k: string]: any}) => {
160
- acc[item] = formData;
161
- });
162
-
163
- return acc;
164
- }, Promise.resolve({}))));
165
- };
166
-
167
- export const getUserById = async (id: string) => {
168
- return await firebaseQuery.getDocData(["users", id]) as UserData;
169
- };
170
-
171
- /* export const getUsersByType = async (q: Query, setState:SetStateAction<any>, uid:string, lim:number, limitType?:"start"|"end") => {
172
- if (limitType === "end") {
173
- q = query(q, endBefore(uid), limitToLast(lim));
174
- } else {
175
- q = query(q, startAfter(uid), limit(lim));
176
- }
177
- return firebaseQuery.collectionSnapshot(q, setState);
178
- };*/
179
-
180
- export const getPlacementbyId = async (pid: string, setState:SetStateAction<any>) => {
181
- return firebaseQuery.documentSnapshot(["placements", pid], setState);
182
- };
183
-
184
- export const getOrganisation = async (user: UserData) => {
185
- return await firebaseQuery.getDocData([user.product, user.oId]);
186
- };
187
-
188
- export const getPlacementsWhere = async ({w=[], oId, raw=false}:{w:QueryConstraint[]|QueryConstraint, oId?:string, uid?:string, raw?:boolean}) => {
189
- console.log("query", JSON.stringify([...(oId ? [where("oId", "==", oId)] : []), ...pathToArr(w)]));
190
- return await firebaseQuery.getDocsWhere("placements", [...(oId ? [where("oId", "==", oId)] : []), ...pathToArr(w)], raw);
191
- };
192
-
193
- export const checkPlacementConflicts = async (instituteId:string, userGroupId:string) => {
194
- const q = query(collection(db, "placements"), where("oId", "==", instituteId), where("userGroup", "==", userGroupId));
195
-
196
- return (await getDocs(q)).size;
197
- };
1
+ import {collection, getDocs, limit, orderBy, query, QueryConstraint, where} from "firebase/firestore";
2
+ import {getDownloadURL, listAll, ref, StorageReference} from "firebase/storage";
3
+ import {SetStateAction} from "react";
4
+ import {BillingPackage, CohortData, InstituteData, NotificationObject, PlacementListing, ProviderData, UserData, UserGroupData} from "../typeDefinitions";
5
+ import {db, storage} from "./firebaseConfig";
6
+ import FirebaseQuery from "./firebaseQuery";
7
+ import {pathToArr, sortByReverseStringLength} from "./util";
8
+
9
+ const firebaseQuery = new FirebaseQuery();
10
+
11
+ export const getStaffRolesForStudent = async (studentFields:string[], product:string, userObject:UserData) => {
12
+ const roleWithStudent = await firebaseQuery.getDocsWhere(
13
+ ["staffRoles"],
14
+ where("filters.students", "array-contains", userObject.id));
15
+
16
+ const roleWithFilters = await studentFields.reduce(async (acc, field) => {
17
+ if (!userObject.details[field as keyof typeof userObject]) {
18
+ return acc;
19
+ }
20
+ const roles = await firebaseQuery.getDocsWhere(
21
+ ["staffRoles"],
22
+ where(`filters.fields.${field}`, "==", userObject.details[field as keyof typeof userObject])) as {[key:string]: unknown};
23
+
24
+ if (Object.keys(roles).length > 0) {
25
+ acc = {...acc, ...roles};
26
+ }
27
+ return acc;
28
+ }, Promise.resolve({}));
29
+
30
+ return {...roleWithFilters, ...roleWithStudent};
31
+ };
32
+
33
+ export const searchUsers = async (userType:"Staff"|"Students", name:string, user:UserData, lim=5, constraints:QueryConstraint[]=[]) => {
34
+ if (name.length < 3) {
35
+ return {};
36
+ }
37
+ // This means we search for the longest string first, thereby probably getting the fewest results.
38
+ const sortedNameList = sortByReverseStringLength(name.split(" "));
39
+
40
+ const unfilteredUsersByForename = await firebaseQuery.getDocsWhere(
41
+ "users",
42
+ [where("userType", "==", userType),
43
+ where("oId", "==", user.oId),
44
+ where("product", "==", user.product),
45
+ where("status", "==", "active"),
46
+ ...constraints,
47
+ where("details.forename", ">=", sortedNameList[0]),
48
+ where("details.forename", "<=", sortedNameList[0]+ "\uf8ff"),
49
+ limit(lim)]) as {[key:string]: UserData};
50
+ const unfilteredUsersBySurname = await firebaseQuery.getDocsWhere(
51
+ "users",
52
+ [where("userType", "==", userType),
53
+ where("product", "==", user.product),
54
+ where("oId", "==", user.oId),
55
+ where("status", "==", "active"),
56
+ ...constraints,
57
+ where("details.surname", ">=", sortedNameList[0]),
58
+ where("details.surname", "<=", sortedNameList[0]+ "\uf8ff"),
59
+ limit(lim)]) as {[key:string]: UserData};
60
+
61
+ let userResults = {...unfilteredUsersByForename, ...unfilteredUsersBySurname};
62
+ sortedNameList.shift();
63
+ sortedNameList.forEach((name) => {
64
+ userResults = Object.fromEntries(Object.entries(userResults).filter(([, user]) => user.details.forename.includes(name) || user.details.surname.includes(name)));
65
+ });
66
+
67
+ return userResults;
68
+ };
69
+
70
+ type OldUserData = {
71
+ userGroup?: string,
72
+ cohort?: string,
73
+ }
74
+
75
+ export const getUser = async (uid: string, setState: SetStateAction<any>) => {
76
+ let oldUser:OldUserData = {};
77
+ let groupData = {};
78
+ let cohortData = {};
79
+ let packageData = {};
80
+
81
+ console.log("Fetching user");
82
+
83
+ firebaseQuery.documentSnapshot(["users", uid], async (user: UserData) => {
84
+ console.log("user", user);
85
+ if (user.userGroup && user.userGroup !== "admin") {
86
+ // Always set the groupData, but only get it if the user group has changed.keyof
87
+ if (oldUser?.userGroup !== user.userGroup) {
88
+ groupData = await firebaseQuery.getDocData(["userGroups", user.userGroup]);
89
+ }
90
+ }
91
+ user.groupData = groupData as UserGroupData;
92
+
93
+ if (user.product === "providers") {
94
+ // Always set the groupData, but only get it if the user group has changed.keyof
95
+ if (oldUser?.userGroup !== user.userGroup) {
96
+ const provider = await firebaseQuery.getDocData(["providers", user.oId]) as ProviderData;
97
+ packageData = await firebaseQuery.getDocData(["billing", provider.package]) as BillingPackage;
98
+ }
99
+ }
100
+ user.packageData = packageData as BillingPackage;
101
+
102
+ if (user.cohort) {
103
+ // Always set the groupData, but only get it if the user group has changed.keyof
104
+ if (oldUser?.cohort !== user.cohort) {
105
+ cohortData = await firebaseQuery.getDocData(["cohorts", user.cohort]);
106
+ }
107
+ }
108
+ user.cohortData = cohortData as CohortData;
109
+
110
+ oldUser = user;
111
+ setState(user)
112
+ });
113
+ };
114
+
115
+ export const getNotifications = async (user: UserData, setState: SetStateAction<any>) => {
116
+ const updateNotifications = (notifications:{[key:string]: NotificationObject}, type:"user"|"org") => {
117
+ setState((old:{[key:string]: NotificationObject}) => {
118
+ const concatenatedNotifications = {
119
+ ...old,
120
+ ...Object.fromEntries(
121
+ Object.entries(notifications)
122
+ .map(([k, v]) => [k, {...v, notifType: type}])
123
+ ),
124
+ };
125
+ return Object.fromEntries(Object.entries(concatenatedNotifications).sort(([, a], [, b]) => b.created.toMillis() - a.created.toMillis()));
126
+ });
127
+ };
128
+
129
+ type NotifQuery = [string[], QueryConstraint|QueryConstraint[]];
130
+
131
+ const userNotifications:NotifQuery = [["users", user.id, "notifications"], [orderBy("created", "desc"), limit(10)]]; /* , limit(10) */
132
+ firebaseQuery.getDocsWhere(userNotifications[0], userNotifications[1]).then((s) => {
133
+ updateNotifications(s as {[key:string]: NotificationObject}, "user");
134
+ });
135
+
136
+ if (user.oId) {
137
+ let notificationsQuery:NotifQuery;
138
+
139
+ if (user.userGroup === "admin") {
140
+ notificationsQuery = [[user.product, user.oId, "notifications"], [orderBy("created", "desc"), limit(10)]]; /* , limit(10) */
141
+ } else {
142
+ notificationsQuery = [[user.product, user.oId, "notifications"], [where("viewableBy", "array-contains-any", [user.id, user.userGroup]), orderBy("created", "desc")]]; /* , limit(10) */
143
+ }
144
+ firebaseQuery.getDocsWhere(notificationsQuery[0], notificationsQuery[1]).then((s) => {
145
+ updateNotifications(s as {[key:string]: NotificationObject}, "org");
146
+ });
147
+ }
148
+ // Only gets notifications that user can view, either by ID or usergroup. Once user not in group, can no longer see notifications.
149
+
150
+ // getCollectionSnapshot(notificationsQuery[0], setState, notificationsQuery[1])
151
+ };
152
+
153
+
154
+ export const getFiles = async (path: string[]|string) => {
155
+ const files = await listAll(ref(storage, ...pathToArr(path)));
156
+
157
+ return (await ((Array.from(files.items) as Array<StorageReference>).reduce(async (acc, item) => {
158
+ const url = await getDownloadURL(item);
159
+ const entry = {name: item.name, url: url};
160
+
161
+
162
+ if (!(await acc).includes(entry)) {
163
+ (await acc).push(entry);
164
+ }
165
+ return acc;
166
+ }, Promise.resolve([] as Array<{name: string, url: string}>))));
167
+ };
168
+
169
+
170
+ export const getFormsFromId = async (path: string[]|string, forms: string[]) => {
171
+ return (await (Array.from(forms).reduce(async (acc: {[k: string]: any}, item: string) => {
172
+ const formData = typeof item === "object" ? item : await firebaseQuery.getDocData([...pathToArr(path), item]);
173
+ console.log("formData", formData);
174
+
175
+ acc.then((acc: {[k: string]: any}) => {
176
+ acc[item] = formData;
177
+ });
178
+
179
+ return acc;
180
+ }, Promise.resolve({}))));
181
+ };
182
+
183
+ export const getUserById = async (id: string, setState?: SetStateAction<any>, getGroupData=true) => {
184
+ if (!setState) {
185
+ const user = await firebaseQuery.getDocData(["users", id]) as UserData;
186
+ if (getGroupData) {
187
+ user.groupData = user.userGroup && user.userGroup !== "admin" ? await firebaseQuery.getDocData(["userGroups", user.userGroup]) as UserGroupData : undefined
188
+ }
189
+ return user;
190
+ }
191
+ firebaseQuery.documentSnapshot(["users", id], async (user: UserData) => {
192
+ if (getGroupData) {
193
+ user.groupData = user.userGroup && user.userGroup !== "admin" ? await firebaseQuery.getDocData(["userGroups", user.userGroup]) as UserGroupData : undefined
194
+ }
195
+ setState(user);
196
+ });
197
+ return;
198
+ };
199
+
200
+ /* export const getUsersByType = async (q: Query, setState:SetStateAction<any>, uid:string, lim:number, limitType?:"start"|"end") => {
201
+ if (limitType === "end") {
202
+ q = query(q, endBefore(uid), limitToLast(lim));
203
+ } else {
204
+ q = query(q, startAfter(uid), limit(lim));
205
+ }
206
+ return firebaseQuery.collectionSnapshot(q, setState);
207
+ };*/
208
+
209
+ export const getPlacementbyId = async (pid: string, setState:SetStateAction<any>) => {
210
+ return firebaseQuery.documentSnapshot(["placements", pid], setState);
211
+ };
212
+
213
+ export const getOrganisation = async (user: UserData, setOrg: (data: InstituteData|ProviderData) => void) => {
214
+ return firebaseQuery.documentSnapshot([user.product, user.oId], setOrg);
215
+ };
216
+
217
+ export const getPlacementsWhere = async ({w=[], oId, uid, raw=false}:{w:QueryConstraint[]|QueryConstraint, oId?:string, uid?:string, raw?:boolean}) => {
218
+ return await firebaseQuery.getDocsWhere("placements", [...(oId ? [where("oId", "==", oId)] : []), ...(uid ? [where("uid", "==", uid)] : []), ...pathToArr(w)], raw);
219
+ };
220
+
221
+ export const checkPlacementConflicts = async (instituteId:string, userGroupId:string) => {
222
+ const q = query(collection(db, "placements"), where("oId", "==", instituteId), where("userGroup", "==", userGroupId));
223
+
224
+ return (await getDocs(q)).size;
225
+ };
226
+
227
+ export const getPlacementListingsById = async (placementListings: string[]) => {
228
+ const placements = await Promise.all(placementListings.map(async (listingId) => {
229
+ return [listingId, await firebaseQuery.getDocData(["placementListings", listingId]).catch(() => false) as PlacementListing];
230
+ })) as [string, PlacementListing|false][];
231
+
232
+ return placements.filter(([_, v]) => v !== false) as [string, PlacementListing][];
233
+ }
234
+
235
+