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