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.
Files changed (86) hide show
  1. package/.eslintrc.js +40 -40
  2. package/.gitattributes +2 -2
  3. package/lib/constants.js +10 -1
  4. package/lib/constants.js.map +1 -1
  5. package/lib/features/config.d.ts +133 -133
  6. package/lib/features/config.js +35 -35
  7. package/lib/features/contacts/contacts.d.ts +75 -75
  8. package/lib/features/contacts/contacts.js +105 -105
  9. package/lib/features/downtime/useDowntime.d.ts +11 -11
  10. package/lib/features/downtime/useDowntime.js +22 -22
  11. package/lib/features/placements/studentPlacements/studentPlacementsSlice.d.ts +63 -63
  12. package/lib/features/placements/studentPlacements/studentPlacementsSlice.js +81 -81
  13. package/lib/features/providerPlacements/providerPlacementsSlice.d.ts +19 -19
  14. package/lib/features/providerPlacements/providerPlacementsSlice.js +24 -24
  15. package/lib/features/studentPlacements/studentPlacementsSlice.d.ts +62 -62
  16. package/lib/features/studentPlacements/studentPlacementsSlice.js +87 -87
  17. package/lib/features/studentPlacements/useStudentPlacements.d.ts +6 -6
  18. package/lib/features/studentPlacements/useStudentPlacements.js +18 -18
  19. package/lib/features/userSlice.d.ts +26 -26
  20. package/lib/features/userSlice.js +23 -23
  21. package/lib/features/users/useUserFunctions.d.ts +25 -25
  22. package/lib/features/users/useUserFunctions.js +124 -124
  23. package/lib/features/users/userSlice.d.ts +46 -46
  24. package/lib/features/users/userSlice.js +48 -48
  25. package/lib/firebase/firebase.d.ts +1 -1
  26. package/lib/firebase/firebase.js +6 -2
  27. package/lib/firebase/firebase.js.map +1 -1
  28. package/lib/firebase/readDatabase.js +3 -1
  29. package/lib/firebase/readDatabase.js.map +1 -1
  30. package/lib/hooks.d.ts +33 -5
  31. package/lib/hooks.js +143 -107
  32. package/lib/hooks.js.map +1 -1
  33. package/lib/images/GatsbyBenchmarks.d.ts +1 -2
  34. package/lib/reduxHooks.d.ts +1 -66
  35. package/lib/reduxHooks.js +9 -69
  36. package/lib/reduxHooks.js.map +1 -1
  37. package/lib/tasksAndTips.d.ts +2 -2
  38. package/lib/tasksAndTips.js +37 -6
  39. package/lib/tasksAndTips.js.map +1 -1
  40. package/lib/typeDefinitions.d.ts +50 -5
  41. package/lib/util.d.ts +1 -1
  42. package/lib/util.js +12 -1
  43. package/lib/util.js.map +1 -1
  44. package/package.json +52 -56
  45. package/src/DatabaseDefinitions.ts +18 -18
  46. package/src/apiCalls.ts +128 -128
  47. package/src/config.ts +50 -50
  48. package/src/constants.ts +796 -787
  49. package/src/databaseTypes.ts +42 -42
  50. package/src/features/analytics/useAnalytics.tsx +63 -63
  51. package/src/features/contacts/contactsSlice.ts +147 -147
  52. package/src/features/contacts/useContacts.tsx +73 -73
  53. package/src/features/dropdown/useDropdown.tsx +52 -52
  54. package/src/features/global/downtime/useDowntime.tsx +23 -23
  55. package/src/features/global/users/useUserFunctions.tsx +132 -132
  56. package/src/features/jobs/jobsSlice.ts +71 -71
  57. package/src/features/placements/studentPlacements/activePlacement.ts +68 -68
  58. package/src/features/placements/studentPlacements/completedStudentPlacementsSlice.ts +97 -97
  59. package/src/features/placements/studentPlacements/upcomingStudentPlacementsSlice.ts +108 -108
  60. package/src/features/placements/studentPlacements/useStudentPlacements.tsx +9 -9
  61. package/src/features/placements/types.ts +10 -10
  62. package/src/features/referrals/useReferrals.tsx +56 -56
  63. package/src/features/updates/useUpdates.tsx +38 -38
  64. package/src/firebase/firebase.tsx +149 -145
  65. package/src/firebase/firebaseConfig.tsx +45 -45
  66. package/src/firebase/firebaseQuery.tsx +151 -151
  67. package/src/firebase/persistence.ts +84 -84
  68. package/src/firebase/readDatabase.tsx +236 -235
  69. package/src/firebase/util.tsx +352 -352
  70. package/src/firebase/writeDatabase.tsx +77 -77
  71. package/src/hooks.tsx +4353 -4323
  72. package/src/images/GatsbyBenchmarks.tsx +711 -711
  73. package/src/images/LogFuturePlacement.jsx +64 -64
  74. package/src/images/LogPreviousPlacement.jsx +228 -228
  75. package/src/images/gatsby_benchmarks.svg +466 -466
  76. package/src/images/log_future_placement.svg +114 -114
  77. package/src/images/log_previous_placement.svg +199 -199
  78. package/src/index.ts +34 -34
  79. package/src/readDatabase.tsx +3 -3
  80. package/src/reduxHooks.ts +232 -297
  81. package/src/tasksAndTips.ts +1209 -1177
  82. package/src/tutorialTips.ts +58 -58
  83. package/src/typeDefinitions.ts +1003 -958
  84. package/src/util.ts +160 -150
  85. package/tsconfig.dev.json +5 -5
  86. 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
+
@@ -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 { documentId, 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, CohortData, Contact, EmailTemplate, InstituteData, PlacementListing, ProviderData, StudentPlacementData, UserData, UserGroupData } from "./typeDefinitions"
12
- import {getOrganisation, 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.userType !== "Students") return {error: "Unauthorized"};
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
- if (!user || user?.product !== "institutes" || user.userType !== "Staff") return {error: "Unauthorized"};
166
-
167
- const firebaseQuery = new FirebaseQuery();
168
- const dispatch = useAppDispatch();
169
- const {userGroups, forms, institute} = useInstitute({user})
170
- const [cohorts, setCohorts] = useState<{[key:string]: CohortData}>();
171
- const [emailTemplates, setEmailTemplates] = useState<{[key:string]: EmailTemplate}>();
172
-
173
-
174
- useEffect(() => {
175
- const cohortConstraints = [where("oId", "==", user.oId)];
176
- if (user.userGroup !== "admin") {
177
- if (user.viewAddresses !== "all") {
178
- cohortConstraints.push(where("addressId", "in", user.visibleAddresses));
179
- }
180
- if (user.viewCohorts !== "all") {
181
- cohortConstraints.push(where(documentId(), "in", user.visibleCohorts));
182
- }
183
- }
184
- firebaseQuery.collectionSnapshot(setCohorts, "cohorts", cohortConstraints);
185
- firebaseQuery.collectionSnapshot(setEmailTemplates, "emailTemplates", [where("product", "==", user.product), where("oId", "==", user.oId)]);
186
- }, [user.oId, user.userGroup, user.viewAddresses, user.viewCohorts, user.visibleAddresses, user.visibleCohorts, user.product])
187
-
188
- const getJobById = async (id: string) => {
189
- try {
190
- const job = await firebaseQuery.getDocData(["jobs", id])
191
- return job
192
-
193
- } catch (error) {
194
- throw error
195
- }
196
- }
197
-
198
- return {
199
- jobs: {
200
- setJobs: async (jobs: {[jobId: string]: Job}) => dispatch(setJobs(jobs)),
201
- addJob: async ({job, jobId} : {job: Partial<Job>, jobId: string}) => dispatch(addJob({job: job, jobId: jobId})),
202
- setMarkRead: async (payload) => dispatch(setMarkRead(payload)),
203
- setJobStatus: async ({jobId, status}: {jobId: string, status: string}) => dispatch(setJobStatus({jobId: jobId, status: status})),
204
- updateJob: async ({jobId, data}: {jobId: string, data: string}) => dispatch(updateJob({jobId: jobId, data: data})),
205
- getById: getJobById
206
- },
207
- institute,
208
- userGroups,
209
- forms,
210
- cohorts,
211
- emailTemplates,
212
- }
213
- }
214
-
215
- export function useInstitute({user}: {user: UserData}) {
216
- if (!user || user?.product !== "institutes") return {error: "Unauthorized"};
217
-
218
- const [userGroups, setUserGroups] = useState<{[key:string]: UserGroupData}>();
219
- const [forms, setForms] = useState<{[key:string]: unknown}>();
220
- const [institute, setInstitute] = useState<InstituteData>();
221
- const firebaseQuery = new FirebaseQuery();
222
-
223
-
224
- useEffect(() => {
225
- getOrganisation(user, (data) => setInstitute(data as InstituteData));
226
- firebaseQuery.collectionSnapshot(setUserGroups, "userGroups", [where("oId", "==", user.oId), where("product", "==", user.product)]);
227
- firebaseQuery.collectionSnapshot(setForms, "forms", [where("oId", "==", user.oId), where("product", "==", user.product)]);
228
- }, [user.product, user.oId])
229
-
230
- return {
231
- userGroups,
232
- forms,
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
  // }