placementt-core 11.0.533 → 11.0.892
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.
- package/lib/constants.d.ts +13 -1
- package/lib/constants.js +86 -1
- package/lib/constants.js.map +1 -1
- package/lib/features/analytics/useAnalytics.d.ts +2 -0
- package/lib/features/analytics/useAnalytics.js +22 -19
- package/lib/features/analytics/useAnalytics.js.map +1 -1
- package/lib/features/global/downtime/useDowntime.d.ts +1 -0
- package/lib/features/global/downtime/useDowntime.js +9 -7
- package/lib/features/global/downtime/useDowntime.js.map +1 -1
- package/lib/features/global/users/useUserFunctions.js +1 -1
- package/lib/features/global/users/useUserFunctions.js.map +1 -1
- package/lib/features/jobs/jobsSlice.d.ts +10 -2
- package/lib/features/jobs/jobsSlice.js +5 -2
- package/lib/features/jobs/jobsSlice.js.map +1 -1
- package/lib/features/placements/studentPlacements/activePlacement.d.ts +5 -1
- package/lib/features/placements/studentPlacements/activePlacement.js +7 -3
- package/lib/features/placements/studentPlacements/activePlacement.js.map +1 -1
- package/lib/features/placements/studentPlacements/completedStudentPlacementsSlice.d.ts +3 -2
- package/lib/features/placements/studentPlacements/completedStudentPlacementsSlice.js +4 -1
- package/lib/features/placements/studentPlacements/completedStudentPlacementsSlice.js.map +1 -1
- package/lib/features/placements/studentPlacements/upcomingStudentPlacementsSlice.d.ts +2 -2
- package/lib/features/placements/studentPlacements/upcomingStudentPlacementsSlice.js +1 -1
- package/lib/features/placements/studentPlacements/upcomingStudentPlacementsSlice.js.map +1 -1
- package/lib/features/placements/studentPlacements/useStudentPlacements.d.ts +2 -12
- package/lib/features/placements/studentPlacements/useStudentPlacements.js +1 -26
- package/lib/features/placements/studentPlacements/useStudentPlacements.js.map +1 -1
- package/lib/features/updates/useUpdates.d.ts +1 -0
- package/lib/features/updates/useUpdates.js +13 -12
- package/lib/features/updates/useUpdates.js.map +1 -1
- package/lib/firebase/firebase.d.ts +5 -3
- package/lib/firebase/firebase.js +23 -12
- package/lib/firebase/firebase.js.map +1 -1
- package/lib/firebase/firebaseConfig.js.map +1 -1
- package/lib/firebase/firebaseQuery.d.ts +6 -2
- package/lib/firebase/firebaseQuery.js +11 -3
- package/lib/firebase/firebaseQuery.js.map +1 -1
- package/lib/firebase/readDatabase.d.ts +2 -4
- package/lib/firebase/readDatabase.js +30 -5
- package/lib/firebase/readDatabase.js.map +1 -1
- package/lib/firebase/writeDatabase.d.ts +6 -2
- package/lib/firebase/writeDatabase.js +2 -1
- package/lib/firebase/writeDatabase.js.map +1 -1
- package/lib/hooks.d.ts +277 -192
- package/lib/hooks.js +1437 -704
- package/lib/hooks.js.map +1 -1
- package/lib/reduxHooks.d.ts +122 -5
- package/lib/reduxHooks.js +132 -29
- package/lib/reduxHooks.js.map +1 -1
- package/lib/tasksAndTips.d.ts +19 -7
- package/lib/tasksAndTips.js +637 -164
- package/lib/tasksAndTips.js.map +1 -1
- package/lib/typeDefinitions.d.ts +321 -110
- package/lib/util.d.ts +15 -3
- package/lib/util.js +47 -10
- package/lib/util.js.map +1 -1
- package/package.json +7 -4
- package/src/constants.ts +91 -3
- package/src/features/analytics/useAnalytics.tsx +25 -17
- package/src/features/global/downtime/useDowntime.tsx +11 -7
- package/src/features/global/users/useUserFunctions.tsx +1 -1
- package/src/features/jobs/jobsSlice.ts +9 -3
- package/src/features/placements/studentPlacements/activePlacement.ts +8 -3
- package/src/features/placements/studentPlacements/completedStudentPlacementsSlice.ts +5 -2
- package/src/features/placements/studentPlacements/upcomingStudentPlacementsSlice.ts +2 -2
- package/src/features/placements/studentPlacements/useStudentPlacements.tsx +4 -28
- package/src/features/updates/useUpdates.tsx +14 -12
- package/src/firebase/firebase.tsx +26 -15
- package/src/firebase/firebaseConfig.tsx +1 -1
- package/src/firebase/firebaseQuery.tsx +11 -3
- package/src/firebase/readDatabase.tsx +34 -6
- package/src/firebase/writeDatabase.tsx +3 -1
- package/src/hooks.tsx +1804 -935
- package/src/reduxHooks.ts +144 -32
- package/src/tasksAndTips.ts +689 -166
- package/src/typeDefinitions.ts +373 -109
- package/src/util.ts +63 -18
package/src/reduxHooks.ts
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
|
-
import { where } from "firebase/firestore"
|
|
1
|
+
import { documentId, orderBy, where } from "firebase/firestore"
|
|
2
2
|
import { useEffect, useState } from "react"
|
|
3
3
|
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"
|
|
4
4
|
import { AppDispatch, RootState } from "./config"
|
|
5
5
|
import { addContact, deleteContact, setContacts, updateContact } from "./features/contacts/contactsSlice"
|
|
6
|
-
import { Job, addJob, setJobStatus, setJobs, setMarkRead } from "./features/jobs/jobsSlice"
|
|
7
|
-
import { fetchActivePlacement } from "./features/placements/studentPlacements/activePlacement"
|
|
6
|
+
import { Job, addJob, setJobStatus, setJobs, setMarkRead, updateJob } from "./features/jobs/jobsSlice"
|
|
7
|
+
import { editActivePlacement, fetchActivePlacement, setActivePlacement } from "./features/placements/studentPlacements/activePlacement"
|
|
8
8
|
import { addCompletedStudentPlacements, deleteCompletedStudentPlacement, setCompletedStudentPlacements, updateCompletedStudentPlacement } from "./features/placements/studentPlacements/completedStudentPlacementsSlice"
|
|
9
9
|
import { addUpcomingStudentPlacements, deleteUpcomingStudentPlacement, setUpcoming, setUpcomingStudentPlacements, updateUpcomingStudentPlacement } from "./features/placements/studentPlacements/upcomingStudentPlacementsSlice"
|
|
10
10
|
import FirebaseQuery from "./firebase/firebaseQuery"
|
|
11
|
-
import { Address, Application, Contact, PlacementListing, ProviderData, StudentPlacementData, UserData } from "./typeDefinitions"
|
|
11
|
+
import { Address, Application, CohortData, Contact, EmailTemplate, InstituteData, PlacementListing, ProviderData, StudentPlacementData, UserData, UserGroupData } from "./typeDefinitions"
|
|
12
|
+
import {getOrganisation, getPlacementsWhere} from "./firebase/readDatabase"
|
|
13
|
+
import {convertDate} from "./firebase/util"
|
|
12
14
|
|
|
13
15
|
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
|
|
14
16
|
export const useAppDispatch = () => useDispatch<AppDispatch>();
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
export function useStudent({user} : {user: UserData}) {
|
|
18
|
-
if (!user || user.
|
|
20
|
+
if (!user || user.userType !== "Students") return {error: "Unauthorized"};
|
|
19
21
|
|
|
20
22
|
const upcomingPlacements = useAppSelector((state) => state.upcomingStudentPlacements.values)
|
|
21
23
|
const completedPlacements = useAppSelector((state) => state.completedStudentPlacements.values)
|
|
22
24
|
const activePlacement = useAppSelector((state) => state.activePlacement.values)
|
|
23
25
|
const upcoming = useAppSelector((state) => state.upcomingStudentPlacements.upcoming)
|
|
24
26
|
const contacts = useAppSelector((state) => state.contacts.values)
|
|
25
|
-
const [applications, setApplications] = useState<{[key: string]: Application&{listing: PlacementListing, provider: ProviderData, address: Address}}>();
|
|
27
|
+
const [applications, setApplications] = useState<{[key: string]: Application&{listing: PlacementListing|false, provider: ProviderData|false, address: Address}}>();
|
|
26
28
|
const firebaseQuery = new FirebaseQuery();
|
|
27
29
|
|
|
28
30
|
const dispatch = useAppDispatch();
|
|
@@ -41,35 +43,52 @@ export function useStudent({user} : {user: UserData}) {
|
|
|
41
43
|
firebaseQuery.collectionSnapshot(async (fApplications: {[key: string]: Application}) => {
|
|
42
44
|
|
|
43
45
|
const applicationsWithProviderAndListing:{[key: string]: Application&{listing: PlacementListing, provider: ProviderData, address: Address}} = Object.fromEntries(await Promise.all(Object.entries(fApplications).map(async ([id, application]) => {
|
|
44
|
-
const provider = await firebaseQuery.getDocData(["providers", application.providerId]) as ProviderData;
|
|
45
|
-
const listing
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return [id, {...application, listing: listing, provider: provider, address: address}];
|
|
46
|
+
const provider = await firebaseQuery.getDocData(["providers", application.providerId]).catch(() => false) as ProviderData|false;
|
|
47
|
+
const listing = await firebaseQuery.getDocData(["placementListings", application.listingId]).catch(() => false) as PlacementListing|false;
|
|
48
|
+
return [id, {...application, listing: listing, provider: provider}];
|
|
49
49
|
})));
|
|
50
50
|
|
|
51
51
|
setApplications(applicationsWithProviderAndListing);
|
|
52
52
|
|
|
53
53
|
}, "applications", applicationsConstraints);
|
|
54
|
-
}, [
|
|
55
|
-
|
|
54
|
+
}, [user.id]);
|
|
55
|
+
/*
|
|
56
56
|
useEffect(() => {
|
|
57
57
|
if (!user.id) return
|
|
58
58
|
dispatch(fetchActivePlacement({userId: user.id}))
|
|
59
|
-
}, [dispatch, user.id, upcomingPlacements])
|
|
59
|
+
}, [dispatch, user.id, upcomingPlacements]);
|
|
60
|
+
*/
|
|
61
|
+
const fetchUpcomingPlacements = () => {
|
|
62
|
+
const constraints = [where("uid", "==", user.id), where("inProgress", "==", true), orderBy("startDate")]
|
|
63
|
+
firebaseQuery.collectionSnapshot(setUpcomingStudentPlacements, "placements", constraints, dispatch);
|
|
64
|
+
}
|
|
60
65
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
66
|
+
const fetchCompletedPlacements = () => {
|
|
67
|
+
const constraints = [where("uid", "==", user.id), where("completed", "==", true), orderBy("startDate")]
|
|
68
|
+
firebaseQuery.collectionSnapshot(setCompletedStudentPlacements, "placements", constraints, dispatch);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const fetchContacts = () => {
|
|
72
|
+
const constraints = [where("uid", "==", user.id)]
|
|
73
|
+
firebaseQuery.collectionSnapshot(setContacts, "contacts", constraints, dispatch);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const updateUpcomingPlacement = () => {
|
|
64
77
|
if (!upcomingPlacements || !Object.entries(upcomingPlacements).length) {
|
|
65
78
|
dispatch(setUpcoming(undefined));
|
|
66
79
|
return;
|
|
67
80
|
}
|
|
68
81
|
const upcomingPlacement = Object.entries(upcomingPlacements).find(([, v]) => new Date(v.startDate).getTime() > today.getTime())
|
|
69
82
|
upcomingPlacement ? dispatch(setUpcoming(upcomingPlacement[1])) : dispatch(setUpcoming(undefined))
|
|
83
|
+
}
|
|
70
84
|
|
|
71
|
-
|
|
72
|
-
|
|
85
|
+
const updateActivePlacement = () => {
|
|
86
|
+
const key = Object.keys(upcomingPlacements).find((key) => {
|
|
87
|
+
const placement = upcomingPlacements[key]
|
|
88
|
+
return placement.active
|
|
89
|
+
})
|
|
90
|
+
key ? dispatch(setActivePlacement(upcomingPlacements[key])) : dispatch(setActivePlacement(null))
|
|
91
|
+
}
|
|
73
92
|
|
|
74
93
|
const getItemById = async (path: "contacts"|"placements", id: string) => {
|
|
75
94
|
return await firebaseQuery.getDocData([path, id])
|
|
@@ -80,9 +99,9 @@ export function useStudent({user} : {user: UserData}) {
|
|
|
80
99
|
else dispatch(deleteCompletedStudentPlacement({placementId: id}))
|
|
81
100
|
}
|
|
82
101
|
|
|
83
|
-
const handleUpdatePlacement = async (id: string,
|
|
84
|
-
if (upcomingPlacements[id]) dispatch(updateUpcomingStudentPlacement({placementId: id, attributes
|
|
85
|
-
else dispatch(updateCompletedStudentPlacement({placementId: id, attributes
|
|
102
|
+
const handleUpdatePlacement = async (id: string, attributes: Partial<StudentPlacementData>) => {
|
|
103
|
+
if (upcomingPlacements[id]) dispatch(updateUpcomingStudentPlacement({placementId: id, attributes}))
|
|
104
|
+
else dispatch(updateCompletedStudentPlacement({placementId: id, attributes}))
|
|
86
105
|
}
|
|
87
106
|
|
|
88
107
|
const handleAddPlacement = async (formData: StudentPlacementData) => {
|
|
@@ -90,19 +109,46 @@ export function useStudent({user} : {user: UserData}) {
|
|
|
90
109
|
else dispatch(addUpcomingStudentPlacements({formData}))
|
|
91
110
|
}
|
|
92
111
|
|
|
112
|
+
const getUserPlacements = async () => {
|
|
113
|
+
return await getPlacementsWhere({w: where("uid", "==", user?.id)})
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const getPlacementsStart = async (start: Date, end: Date) => {
|
|
117
|
+
return await firebaseQuery.getDocsWhere("placements", [where("uid", "==", user?.id), where("startDate", ">=", convertDate(start, "dbstring")), where("startDate", "<=", convertDate(end, "dbstring"))]) as {[key:string]: StudentPlacementData};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const getPlacementsEnd = async (end: Date) => {
|
|
121
|
+
return await firebaseQuery.getDocsWhere("placements", [where("uid", "==", user?.id), where("endDate", ">=", convertDate(end, "dbstring")), where("endDate", "<=", convertDate(end, "dbstring"))]) as {[key:string]: StudentPlacementData};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const dispatchActivePlacement = () => {
|
|
125
|
+
dispatch(fetchActivePlacement({userId: user.id}))
|
|
126
|
+
}
|
|
127
|
+
|
|
93
128
|
return {
|
|
94
129
|
contacts: {
|
|
95
|
-
add: async (contactForm: Contact) => dispatch(addContact({contactForm: contactForm, userId: user.id})),
|
|
96
|
-
update: async (contactId: string, data: Partial<Contact>) => dispatch(updateContact({contactId: contactId, attributes: data})),
|
|
97
|
-
delete: async (contactId: string) => dispatch(deleteContact({contactId: contactId})),
|
|
130
|
+
add: async (contactForm: Contact) => await dispatch(addContact({contactForm: contactForm, userId: user.id})),
|
|
131
|
+
update: async (contactId: string, data: Partial<Contact>) => await dispatch(updateContact({contactId: contactId, attributes: data})),
|
|
132
|
+
delete: async (contactId: string) => await dispatch(deleteContact({contactId: contactId})),
|
|
98
133
|
contacts,
|
|
134
|
+
fetchContacts,
|
|
99
135
|
getById: async (item: string) => await getItemById("contacts", item)
|
|
100
136
|
},
|
|
137
|
+
|
|
101
138
|
placements: {
|
|
102
139
|
add: async (formData: StudentPlacementData) => await handleAddPlacement(formData),
|
|
103
|
-
update: async (placementId: string,
|
|
140
|
+
update: async (placementId: string, attributes: Partial<StudentPlacementData>) => await handleUpdatePlacement(placementId, attributes),
|
|
104
141
|
delete: async (id: string) => await handleDeletePlacement(id),
|
|
142
|
+
getUserPlacements,
|
|
143
|
+
getPlacementsStart,
|
|
144
|
+
getPlacementsEnd,
|
|
105
145
|
activePlacement,
|
|
146
|
+
editActivePlacement: (attributes: Partial<StudentPlacementData>) => dispatch(editActivePlacement(attributes)),
|
|
147
|
+
updateActivePlacement,
|
|
148
|
+
updateUpcomingPlacement,
|
|
149
|
+
fetchUpcomingPlacements,
|
|
150
|
+
fetchCompletedPlacements,
|
|
151
|
+
dispatchActivePlacement,
|
|
106
152
|
upcoming,
|
|
107
153
|
upcomingPlacements: upcomingPlacements || {},
|
|
108
154
|
completedPlacements: completedPlacements || {},
|
|
@@ -114,10 +160,28 @@ export function useStudent({user} : {user: UserData}) {
|
|
|
114
160
|
|
|
115
161
|
|
|
116
162
|
export function useInstituteStaff({user}: {user: UserData}) {
|
|
163
|
+
if (!user || user?.product !== "institutes" || user.userType !== "Staff") return {error: "Unauthorized"};
|
|
164
|
+
|
|
117
165
|
const firebaseQuery = new FirebaseQuery();
|
|
118
166
|
const dispatch = useAppDispatch();
|
|
167
|
+
const {userGroups, forms, institute} = useInstitute({user})
|
|
168
|
+
const [cohorts, setCohorts] = useState<{[key:string]: CohortData}>();
|
|
169
|
+
const [emailTemplates, setEmailTemplates] = useState<{[key:string]: EmailTemplate}>();
|
|
170
|
+
|
|
119
171
|
|
|
120
|
-
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
const cohortConstraints = [where("oId", "==", user.oId)];
|
|
174
|
+
if (user.userGroup !== "admin") {
|
|
175
|
+
if (user.viewAddresses !== "all") {
|
|
176
|
+
cohortConstraints.push(where("addressId", "in", user.visibleAddresses));
|
|
177
|
+
}
|
|
178
|
+
if (user.viewCohorts !== "all") {
|
|
179
|
+
cohortConstraints.push(where(documentId(), "in", user.visibleCohorts));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
firebaseQuery.collectionSnapshot(setCohorts, "cohorts", cohortConstraints);
|
|
183
|
+
firebaseQuery.collectionSnapshot(setEmailTemplates, "emailTemplates", [where("product", "==", user.product), where("oId", "==", user.oId)]);
|
|
184
|
+
}, [user.oId, user.userGroup, user.viewAddresses, user.viewCohorts, user.visibleAddresses, user.visibleCohorts, user.product])
|
|
121
185
|
|
|
122
186
|
const getJobById = async (id: string) => {
|
|
123
187
|
try {
|
|
@@ -135,27 +199,75 @@ export function useInstituteStaff({user}: {user: UserData}) {
|
|
|
135
199
|
addJob: async ({job, jobId} : {job: Partial<Job>, jobId: string}) => dispatch(addJob({job: job, jobId: jobId})),
|
|
136
200
|
setMarkRead: async (payload) => dispatch(setMarkRead(payload)),
|
|
137
201
|
setJobStatus: async ({jobId, status}: {jobId: string, status: string}) => dispatch(setJobStatus({jobId: jobId, status: status})),
|
|
202
|
+
updateJob: async ({jobId, data}: {jobId: string, data: string}) => dispatch(updateJob({jobId: jobId, data: data})),
|
|
138
203
|
getById: getJobById
|
|
139
|
-
}
|
|
204
|
+
},
|
|
205
|
+
institute,
|
|
206
|
+
userGroups,
|
|
207
|
+
forms,
|
|
208
|
+
cohorts,
|
|
209
|
+
emailTemplates,
|
|
140
210
|
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function useInstitute({user}: {user: UserData}) {
|
|
214
|
+
if (!user || user?.product !== "institutes") return {error: "Unauthorized"};
|
|
215
|
+
|
|
216
|
+
const [userGroups, setUserGroups] = useState<{[key:string]: UserGroupData}>();
|
|
217
|
+
const [forms, setForms] = useState<{[key:string]: unknown}>();
|
|
218
|
+
const [institute, setInstitute] = useState<InstituteData>();
|
|
219
|
+
const firebaseQuery = new FirebaseQuery();
|
|
141
220
|
|
|
142
221
|
|
|
222
|
+
useEffect(() => {
|
|
223
|
+
getOrganisation(user, (data) => setInstitute(data as InstituteData));
|
|
224
|
+
firebaseQuery.collectionSnapshot(setUserGroups, "userGroups", [where("oId", "==", user.oId), where("product", "==", user.product)]);
|
|
225
|
+
firebaseQuery.collectionSnapshot(setForms, "forms", [where("oId", "==", user.oId), where("product", "==", user.product)]);
|
|
226
|
+
}, [user.product, user.oId])
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
userGroups,
|
|
230
|
+
forms,
|
|
231
|
+
institute,
|
|
232
|
+
}
|
|
233
|
+
|
|
143
234
|
}
|
|
144
235
|
|
|
145
236
|
export function useInstituteStudent({user}: {user: UserData}) {
|
|
146
|
-
|
|
237
|
+
if (!user || user?.product !== "institutes" || user.userType !== "Students") return {error: "Unauthorized"};
|
|
147
238
|
|
|
148
|
-
|
|
239
|
+
const {contacts, placements, applications} = useStudent({user});
|
|
240
|
+
const [cohorts, setCohorts] = useState<{[key:string]: CohortData}>();
|
|
241
|
+
const firebaseQuery = new FirebaseQuery();
|
|
242
|
+
const {userGroups, forms, institute} = useInstitute({user})
|
|
243
|
+
|
|
244
|
+
useEffect(() => {
|
|
245
|
+
const isAdmin = user.userGroup === "admin";
|
|
246
|
+
const canViewCohorts = user.viewCohorts !== "none";
|
|
247
|
+
const canViewAddresses = user.viewAddresses !== "none";
|
|
248
|
+
|
|
249
|
+
if (isAdmin || (canViewCohorts && canViewAddresses)) {
|
|
250
|
+
const cohortConstraints = [where("oId", "==", user.oId)];
|
|
251
|
+
firebaseQuery.collectionSnapshot(setCohorts, "cohorts", cohortConstraints);
|
|
252
|
+
} else {
|
|
253
|
+
setCohorts({});
|
|
254
|
+
}
|
|
255
|
+
}, [user.oId, user.id, user.userGroup, user.viewCohorts, user.viewAddresses, user.product]);
|
|
149
256
|
|
|
150
257
|
return {
|
|
151
258
|
contacts,
|
|
152
|
-
placements
|
|
259
|
+
placements,
|
|
260
|
+
institute,
|
|
261
|
+
userGroups,
|
|
262
|
+
forms,
|
|
263
|
+
cohorts,
|
|
264
|
+
applications,
|
|
153
265
|
}
|
|
154
266
|
|
|
155
267
|
}
|
|
156
268
|
|
|
157
269
|
export function useProvider({user}: {user: UserData}) {
|
|
158
|
-
if (!user || user?.product !== "providers") return {};
|
|
270
|
+
if (!user || user?.product !== "providers") return {error: "Unauthorized"};
|
|
159
271
|
|
|
160
272
|
const {jobs} = useInstituteStaff({user});
|
|
161
273
|
|