placementt-core 11.0.803 → 11.0.914

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.
@@ -1,7 +1,7 @@
1
- import {arrayUnion, documentId, orderBy, where} from "firebase/firestore";
1
+ import {arrayUnion, where} from "firebase/firestore";
2
2
  import FirebaseQuery from "./firebase/firebaseQuery";
3
- import {CohortData, InstituteData, OrganisationAddress, PlacementListing, ProviderData, RegistrationRequest, StudentPlacementData, UserData} from "./typeDefinitions";
4
- import {camelCaseToNormal, capitaliseWords, dateToString, getAccess} from "./firebase/util";
3
+ import {CohortData, InstituteData, OrganisationAddress, ProviderData, SchoolData, StudentPlacementData, UserData} from "./typeDefinitions";
4
+ import {getAccess} from "./firebase/util";
5
5
  import { convertDate } from "./firebase/util";
6
6
 
7
7
  const firebaseQuery = new FirebaseQuery;
@@ -10,7 +10,7 @@ type InstituteTipNames = "createCohort"|"addSchools"|"uploadStaff"|"assignStaffR
10
10
  type ProviderTipNames = string
11
11
  type StudentTipNames = string
12
12
 
13
- export type InstituteTaskNames = "missingParentEmail"|"outstandingReminders"|"invalidStaffEmails"|"invalidStudentEmails"|"invalidParentEmails"|"invalidProviderEmails"|"verifyInsurance"|"verifyRiskAssessment"|"verifyDbsCheck"|"inactiveStudents"|"uploadStudents"|"inactiveStaff"|"requiredStage"|"approveExternalPlacement"|"overdueStage"
13
+ export type InstituteTaskNames = "missingParentEmail"|"approveAlumniConversation"|"outstandingReminders"|"invalidStaffEmails"|"invalidStudentEmails"|"invalidParentEmails"|"invalidProviderEmails"|"verifyInsurance"|"verifyRiskAssessment"|"verifyDbsCheck"|"inactiveStudents"|"uploadStudents"|"inactiveStaff"|"requiredStage"|"approveExternalPlacement"|"overdueStage"
14
14
  export type StudentTaskNames = "completeOnboarding"
15
15
  export type ProviderTaskNames = "applicationRequireReview"|"activateStaff"|"requestedVisiblePlacementListings"|"requestedVisibleAddresses"|"completeStudentDocs"|"uploadOnboarding"|"reviewOnboarding"|"completeListing"|"completeAddress"|"registrationRequests"|"placementStarting"|"completeFeedback"|"setUpFeedback"
16
16
 
@@ -34,7 +34,7 @@ type TasksObject = {
34
34
  */
35
35
  type InstituteTipsObject = {
36
36
  [key in InstituteTipNames]: {
37
- callback: (user: UserData, organisation?:InstituteData|ProviderData, additional?:{[key: string]: OrganisationAddress}) => Promise<TaskQueryReturnObject|TaskQueryReturnObject[]>,
37
+ callback: (user: UserData, organisation?:InstituteData&ProviderData, additional?:{[key: string]: OrganisationAddress}) => Promise<TaskQueryReturnObject|TaskQueryReturnObject[]>,
38
38
  };
39
39
  };
40
40
  type ProviderTipsObject = {
@@ -50,7 +50,7 @@ type StudentTipsObject = {
50
50
 
51
51
  export type InstituteTaskObject = {
52
52
  [key in InstituteTaskNames]: {
53
- callback: (user: UserData, organisation:InstituteData|ProviderData, cohort: CohortData|[string, CohortData][]) => Promise<TaskQueryReturnObject|TaskQueryReturnObject[]>,
53
+ callback: ({user, organisation, cohorts, schools}:{user: UserData, organisation:InstituteData&ProviderData, cohorts: CohortData|[string, CohortData][], schools?: SchoolData|[string, SchoolData][]}) => Promise<TaskQueryReturnObject|TaskQueryReturnObject[]>,
54
54
  };
55
55
  };
56
56
 
@@ -199,8 +199,8 @@ const instituteTips:InstituteTipsObject = {
199
199
 
200
200
  const instituteTasks:InstituteTaskObject = {
201
201
  invalidStaffEmails: {
202
- callback: async (user, organisation, cohort) => {
203
- if (!getAccess(user, "viewStaff") || !Array.isArray(cohort)) return;
202
+ callback: async ({user, cohorts}) => {
203
+ if (!getAccess(user, "viewStaff") || !Array.isArray(cohorts)) return;
204
204
 
205
205
  const staffCount = (await firebaseQuery.getCount(["users"], [where("oId", "==", user.oId), where("userType", "==", "Staff"), where("flags", "array-contains", "userEmailFailed")]));
206
206
  if (staffCount > 0) {
@@ -209,14 +209,62 @@ const instituteTasks:InstituteTaskObject = {
209
209
  severity: "error",
210
210
  title: `${staffCount} staff have invalid emails.`,
211
211
  message: `${staffCount} staff accounts have invalid email addresses. Delete and reupload these users.`,
212
- link: "/institutes/cohorts/staff/all",
212
+ link: "/institutes/organisation/staff/all",
213
213
  };
214
214
  }
215
215
  return;
216
216
  },
217
217
  },
218
+ approveAlumniConversation: {
219
+ callback: async ({user, organisation, schools}) => {
220
+ if (!schools) {
221
+ if (!organisation.alumniConversations) return;
222
+ const convos = (await firebaseQuery.getCount(["alumniConversations"], [where("oId", "==", user.oId), where("open", "==", true), where("delivered", "==", "pending")]));
223
+ if (convos > 0) {
224
+ return {
225
+ dismissible: false,
226
+ severity: "info",
227
+ title: `${convos} alumni conversation message${convos > 1 ? "s" : ""} needs approval.`,
228
+ message: `There are ${convos} message${convos > 1 ? "s" : ""} to alumni for you to review and release.`,
229
+ link: "/institutes/network/alumni/conversations",
230
+ };
231
+ }
232
+ return;
233
+ }
234
+ if (!Array.isArray(schools)) {
235
+ // One school
236
+ const convos = (await firebaseQuery.getCount(["alumniConversations"], [where("oId", "==", user.oId), where("schoolId", "==", schools.id), where("open", "==", true), where("delivered", "==", "pending")]));
237
+ if (convos > 0) {
238
+ return {
239
+ dismissible: false,
240
+ severity: "info",
241
+ title: `${convos} alumni conversation message${convos > 1 ? "s" : ""} needs approval.`,
242
+ message: `There are ${convos} message${convos > 1 ? "s" : ""} to alumni for you to review and release.`,
243
+ link: `/institutes/network/alumni/conversations/${schools.id}`,
244
+ };
245
+ }
246
+ return;
247
+ }
248
+
249
+ const items = await Promise.all(schools.map(async ([id, school]) => {
250
+ if (!school.alumniConversations) return;
251
+ const convos = (await firebaseQuery.getCount(["alumniConversations"], [where("oId", "==", user.oId), where("schoolId", "==", id), where("open", "==", true), where("delivered", "==", "pending")]));
252
+ if (convos > 0) {
253
+ return {
254
+ dismissible: false,
255
+ severity: "info",
256
+ title: `${convos} alumni conversation message${convos > 1 ? "s" : ""} needs approval.`,
257
+ message: `${school.name}, has ${convos} outstanding alumni message${convos > 1 ? "s" : ""} to approve. Click to view.`,
258
+ link: `/institutes/network/alumni/conversations/${school.id}`,
259
+ } as TaskQueryReturnObject;
260
+ }
261
+ return;
262
+ }));
263
+ return items.filter((v) => v);
264
+ },
265
+ },
218
266
  invalidStudentEmails: {
219
- callback: async (user, organisation, cohorts) => {
267
+ callback: async ({user, cohorts}) => {
220
268
  if (!getAccess(user, "viewStudents") || user.viewStudents === "none") return;
221
269
 
222
270
  if (!Array.isArray(cohorts)) {
@@ -250,7 +298,7 @@ const instituteTasks:InstituteTaskObject = {
250
298
  },
251
299
  },
252
300
  outstandingReminders: {
253
- callback: async (user, organisation, cohorts) => {
301
+ callback: async ({user, cohorts}) => {
254
302
  if (!Array.isArray(cohorts)) {
255
303
  const reminderCount = (await firebaseQuery.getCount(["reminders"], [where("oId", "==", user.oId), where("uid", "==", user.id), where("dueDate", "<=", convertDate(new Date(), "dbstring") as string), where("cohort", "==", cohorts.id), where("status", "==", "upcoming")]));
256
304
  if (reminderCount > 0) {
@@ -282,7 +330,7 @@ const instituteTasks:InstituteTaskObject = {
282
330
  },
283
331
  },
284
332
  invalidParentEmails: {
285
- callback: async (user, _, cohorts) => {
333
+ callback: async ({user, cohorts}) => {
286
334
  if (!getAccess(user, "signOffPlacements") || user.viewStudents === "none") return;
287
335
 
288
336
  if (!Array.isArray(cohorts)) {
@@ -317,7 +365,7 @@ const instituteTasks:InstituteTaskObject = {
317
365
  },
318
366
  },
319
367
  invalidProviderEmails: {
320
- callback: async (user, organisation, cohorts) => {
368
+ callback: async ({user, cohorts}) => {
321
369
  if (!getAccess(user, "signOffPlacements") || user.viewStudents === "none") return;
322
370
 
323
371
  if (!Array.isArray(cohorts)) {
@@ -352,7 +400,7 @@ const instituteTasks:InstituteTaskObject = {
352
400
  },
353
401
  },
354
402
  requiredStage: {
355
- callback: async (user, _, cohorts) => {
403
+ callback: async ({user, cohorts}) => {
356
404
  if (!getAccess(user, "signOffPlacements") || user.viewStudents === "none") return;
357
405
 
358
406
  if (!Array.isArray(cohorts)) {
@@ -387,7 +435,7 @@ const instituteTasks:InstituteTaskObject = {
387
435
  },
388
436
  },
389
437
  verifyInsurance: {
390
- callback: async (user, _, cohorts) => {
438
+ callback: async ({user, cohorts}) => {
391
439
  if (!getAccess(user, "verifyInsurance") || user.viewStudents === "none") return;
392
440
 
393
441
  if (!Array.isArray(cohorts)) {
@@ -422,7 +470,7 @@ const instituteTasks:InstituteTaskObject = {
422
470
  },
423
471
  },
424
472
  verifyDbsCheck: {
425
- callback: async (user, _, cohorts) => {
473
+ callback: async ({user, cohorts}) => {
426
474
  if (!getAccess(user, "verifyDbsChecks") || user.viewStudents === "none") return;
427
475
 
428
476
  if (!Array.isArray(cohorts)) {
@@ -457,7 +505,7 @@ const instituteTasks:InstituteTaskObject = {
457
505
  },
458
506
  },
459
507
  verifyRiskAssessment: {
460
- callback: async (user, _, cohorts) => {
508
+ callback: async ({user, cohorts}) => {
461
509
  if (!getAccess(user, "verifyRiskAssessments") || user.viewStudents === "none") return;
462
510
 
463
511
  if (!Array.isArray(cohorts)) {
@@ -492,7 +540,7 @@ const instituteTasks:InstituteTaskObject = {
492
540
  },
493
541
  },
494
542
  missingParentEmail: {
495
- callback: async (user, _, cohorts) => {
543
+ callback: async ({user, cohorts}) => {
496
544
  if (!getAccess(user, "editStudents") || user.viewStudents === "none") return;
497
545
  if (!Array.isArray(cohorts)) {
498
546
  const requiresParents = Boolean(cohorts.workflow.find((node) => node.userType === "Parent"))
@@ -539,7 +587,7 @@ const instituteTasks:InstituteTaskObject = {
539
587
  },
540
588
  },
541
589
  inactiveStudents: {
542
- callback: async (user, _, cohorts) => {
590
+ callback: async ({user, cohorts}) => {
543
591
  if (!getAccess(user, "activateStudents") || user.viewStudents === "none") return;
544
592
  if (!Array.isArray(cohorts)) {
545
593
  const constraints = [where("oId", "==", user.oId), where("cohort", "==", cohorts.id), where("status", "==", "inactive")];
@@ -583,7 +631,7 @@ const instituteTasks:InstituteTaskObject = {
583
631
  },
584
632
  },
585
633
  uploadStudents: {
586
- callback: async (user, _, cohorts) => {
634
+ callback: async ({user, cohorts}) => {
587
635
  if (!Array.isArray(cohorts)) return;
588
636
  if (!getAccess(user, "addStudents") || user.viewStudents === "none") return;
589
637
  if (user.product !== "institutes") return;
@@ -609,7 +657,7 @@ const instituteTasks:InstituteTaskObject = {
609
657
  },
610
658
  },
611
659
  inactiveStaff: {
612
- callback: async (user, _, cohorts) => {
660
+ callback: async ({user, cohorts}) => {
613
661
  if (!getAccess(user, "addStaff")) return;
614
662
 
615
663
  if (!Array.isArray(cohorts) || user.product === "students") return;
@@ -630,15 +678,15 @@ const instituteTasks:InstituteTaskObject = {
630
678
  },
631
679
  },
632
680
  overdueStage: {
633
- callback: async (user, _, cohort) => {
634
- console.log(user, cohort);
681
+ callback: async ({user, cohorts}) => {
682
+ console.log(user, cohorts);
635
683
  return undefined;
636
684
  },
637
685
  },
638
686
  approveExternalPlacement: {
639
- callback: async (user, _, cohort) => {
687
+ callback: async ({user, cohorts}) => {
640
688
  if (!getAccess(user, "verifyListings")) return;
641
- if (!Array.isArray(cohort)) return;
689
+ if (!Array.isArray(cohorts)) return;
642
690
  const externalCount = await firebaseQuery.getCount(["placementListings"],
643
691
  [where(`savedBy.${user.oId}.exists`, "==", true), where(`savedBy.${user.oId}.status`, "==", "uploaded"), where("mapConsent", "==", "institute")]);
644
692
  console.log("EXT", externalCount);
@@ -675,408 +723,408 @@ const studentTasks:StudentTaskObject = {
675
723
  }
676
724
  }
677
725
 
678
- const providerTasks:ProviderTaskObject = {
679
- requestedVisibleAddresses: {
680
- callback: async (user) => {
681
- if (!getAccess(user, "addStaff")) return;
682
- const accessRequests = await firebaseQuery.getCount("users", [where("oId", "==", user.oId), where("product", "==", "providers"), orderBy("requestedVisibleAddresses")]) - ((Array.isArray(user?.requestedVisibleAddresses) && user?.requestedVisibleAddresses.length > 0) ? 1 : 0);
683
- if (accessRequests === 0) return;
684
- if (accessRequests === 1) {
685
- const userRequestingAccess = Object.entries(await firebaseQuery.getDocsWhere("users", [where("product", "==", "providers"), where("oId", "==", user.oId), orderBy("requestedVisibleAddresses")]) || {})[0] as [string, UserData];
686
- return {
687
- dismissible: false,
688
- severity: "primary",
689
- title: `${userRequestingAccess[1].details.forename} ${userRequestingAccess[1].details.surname} has requested access to view addresses.`,
690
- message: `Click to review the addresses and grant access to the user.`,
691
- link: `/${user.product}/users/${userRequestingAccess[0]}`,
692
- buttonTitle: "View request",
693
- } as TaskQueryReturnObject;
694
- }
695
-
696
- return {
697
- dismissible: false,
698
- severity: "warning",
699
- title: `Multiple users have requested access to view addresses.`,
700
- message: `Click to review the addresses and grant access to the user.`,
701
- link: `/${user.product}/organisation/staff/all`,
702
- buttonTitle: "View request",
703
- } as TaskQueryReturnObject;
704
- },
705
- },
706
- requestedVisiblePlacementListings: {
707
- callback: async (user) => {
708
- if (!getAccess(user, "addStaff")) return;
709
- const accessRequests = await firebaseQuery.getCount("users", [where("oId", "==", user.oId), where("product", "==", "providers"), orderBy("requestedVisibleListings")])- ((Array.isArray(user?.requestedVisibleListings) && user?.requestedVisibleListings.length > 0) ? 1 : 0);;
710
- if (accessRequests === 0) return;
711
- if (accessRequests === 1) {
712
- const userRequestingAccess = Object.entries(await firebaseQuery.getDocsWhere("users", [where("oId", "==", user.oId), where("product", "==", "providers"), orderBy("requestedVisibleListings")]) || {})[0] as [string, UserData];
713
- return {
714
- dismissible: false,
715
- severity: "primary",
716
- title: `${userRequestingAccess[1].details.forename} ${userRequestingAccess[1].details.surname} has requested access to view placement listings.`,
717
- message: `Click to review the placement listings and grant access to the user.`,
718
- link: `/${user.product}/users/${userRequestingAccess[0]}`,
719
- buttonTitle: "View request",
720
- } as TaskQueryReturnObject;
721
- }
722
-
723
- return {
724
- dismissible: false,
725
- severity: "warning",
726
- title: `Multiple users have requested access to view placement listings.`,
727
- message: `Click to review the placement listings and grant access to the user.`,
728
- link: `/${user.product}/organisation/staff/all`,
729
- buttonTitle: "View request",
730
- } as TaskQueryReturnObject;
731
- },
732
- },
733
- applicationRequireReview: {
734
- callback: async (user) => {
735
- const constraints = [where("providerId", "==", user.oId), where("reqUserType", "==", "Staff"), where("status", "==", "submitted")];
736
-
737
- if (user.userGroup !== "admin") {
726
+ // const providerTasks:ProviderTaskObject = {
727
+ // requestedVisibleAddresses: {
728
+ // callback: async (user) => {
729
+ // if (!getAccess(user, "addStaff")) return;
730
+ // const accessRequests = await firebaseQuery.getCount("users", [where("oId", "==", user.oId), where("product", "==", "providers"), orderBy("requestedVisibleAddresses")]) - ((Array.isArray(user?.requestedVisibleAddresses) && user?.requestedVisibleAddresses.length > 0) ? 1 : 0);
731
+ // if (accessRequests === 0) return;
732
+ // if (accessRequests === 1) {
733
+ // const userRequestingAccess = Object.entries(await firebaseQuery.getDocsWhere("users", [where("product", "==", "providers"), where("oId", "==", user.oId), orderBy("requestedVisibleAddresses")]) || {})[0] as [string, UserData];
734
+ // return {
735
+ // dismissible: false,
736
+ // severity: "primary",
737
+ // title: `${userRequestingAccess[1].details.forename} ${userRequestingAccess[1].details.surname} has requested access to view addresses.`,
738
+ // message: `Click to review the addresses and grant access to the user.`,
739
+ // link: `/${user.product}/users/${userRequestingAccess[0]}`,
740
+ // buttonTitle: "View request",
741
+ // } as TaskQueryReturnObject;
742
+ // }
743
+
744
+ // return {
745
+ // dismissible: false,
746
+ // severity: "warning",
747
+ // title: `Multiple users have requested access to view addresses.`,
748
+ // message: `Click to review the addresses and grant access to the user.`,
749
+ // link: `/${user.product}/organisation/staff/all`,
750
+ // buttonTitle: "View request",
751
+ // } as TaskQueryReturnObject;
752
+ // },
753
+ // },
754
+ // requestedVisiblePlacementListings: {
755
+ // callback: async (user) => {
756
+ // if (!getAccess(user, "addStaff")) return;
757
+ // const accessRequests = await firebaseQuery.getCount("users", [where("oId", "==", user.oId), where("product", "==", "providers"), orderBy("requestedVisibleListings")])- ((Array.isArray(user?.requestedVisibleListings) && user?.requestedVisibleListings.length > 0) ? 1 : 0);;
758
+ // if (accessRequests === 0) return;
759
+ // if (accessRequests === 1) {
760
+ // const userRequestingAccess = Object.entries(await firebaseQuery.getDocsWhere("users", [where("oId", "==", user.oId), where("product", "==", "providers"), orderBy("requestedVisibleListings")]) || {})[0] as [string, UserData];
761
+ // return {
762
+ // dismissible: false,
763
+ // severity: "primary",
764
+ // title: `${userRequestingAccess[1].details.forename} ${userRequestingAccess[1].details.surname} has requested access to view placement listings.`,
765
+ // message: `Click to review the placement listings and grant access to the user.`,
766
+ // link: `/${user.product}/users/${userRequestingAccess[0]}`,
767
+ // buttonTitle: "View request",
768
+ // } as TaskQueryReturnObject;
769
+ // }
770
+
771
+ // return {
772
+ // dismissible: false,
773
+ // severity: "warning",
774
+ // title: `Multiple users have requested access to view placement listings.`,
775
+ // message: `Click to review the placement listings and grant access to the user.`,
776
+ // link: `/${user.product}/organisation/staff/all`,
777
+ // buttonTitle: "View request",
778
+ // } as TaskQueryReturnObject;
779
+ // },
780
+ // },
781
+ // applicationRequireReview: {
782
+ // callback: async (user) => {
783
+ // const constraints = [where("providerId", "==", user.oId), where("reqUserType", "==", "Staff"), where("status", "==", "submitted")];
784
+
785
+ // if (user.userGroup !== "admin") {
738
786
 
739
- if (!user.viewPlacementListings || user.viewPlacementListings === "none") return;
740
- if (!user.viewAddresses || user.viewAddresses === "none") return;
741
-
742
- if (user.viewPlacementListings === "request") {
743
- if (!user.visibleListings || user.visibleListings?.length === 0) return;
744
- constraints.push(where("listingId", 'in', user.visibleListings));
745
- } else {
746
- // viewPlacementListings must be 'all'
747
-
748
- if (user.viewAddresses === "request") {
749
- if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
750
- constraints.push(where("addressId", 'in', user.visibleAddresses));
751
- }
752
- }
753
- }
754
- const applicationCount = await firebaseQuery.getCount("applications", constraints);
755
- if (applicationCount === 0) return;
756
-
757
- return {
758
- dismissible: false,
759
- severity: "primary",
760
- title: `${applicationCount} applications require your review.`,
761
- message: `Click to view ${applicationCount} that require your attention.`,
762
- link: `/${user.product}/placementListings/applicants`,
763
- buttonTitle: "View applications",
764
- } as TaskQueryReturnObject;
765
- },
766
- },
767
- completeStudentDocs: {
768
- callback: async (user) => {
769
- return;
770
- return {} as TaskQueryReturnObject;
771
- },
772
- },
773
- reviewOnboarding: {
774
- callback: async (user) => {
775
- const constraints = [where("providerId", "==", user.oId), where("onboarding.completed.accepted", "==", false), where("onboarding.completed.submitted", "==", true), where("endDate", ">=", dateToString(new Date()))]
776
-
777
- if (user.userGroup !== "admin") {
787
+ // if (!user.viewPlacementListings || user.viewPlacementListings === "none") return;
788
+ // if (!user.viewAddresses || user.viewAddresses === "none") return;
789
+
790
+ // if (user.viewPlacementListings === "request") {
791
+ // if (!user.visibleListings || user.visibleListings?.length === 0) return;
792
+ // constraints.push(where("listingId", 'in', user.visibleListings));
793
+ // } else {
794
+ // // viewPlacementListings must be 'all'
795
+
796
+ // if (user.viewAddresses === "request") {
797
+ // if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
798
+ // constraints.push(where("addressId", 'in', user.visibleAddresses));
799
+ // }
800
+ // }
801
+ // }
802
+ // const applicationCount = await firebaseQuery.getCount("applications", constraints);
803
+ // if (applicationCount === 0) return;
804
+
805
+ // return {
806
+ // dismissible: false,
807
+ // severity: "primary",
808
+ // title: `${applicationCount} applications require your review.`,
809
+ // message: `Click to view ${applicationCount} that require your attention.`,
810
+ // link: `/${user.product}/placementListings/applicants`,
811
+ // buttonTitle: "View applications",
812
+ // } as TaskQueryReturnObject;
813
+ // },
814
+ // },
815
+ // completeStudentDocs: {
816
+ // callback: async (user) => {
817
+ // return;
818
+ // return {} as TaskQueryReturnObject;
819
+ // },
820
+ // },
821
+ // reviewOnboarding: {
822
+ // callback: async (user) => {
823
+ // const constraints = [where("providerId", "==", user.oId), where("onboarding.completed.accepted", "==", false), where("onboarding.completed.submitted", "==", true), where("endDate", ">=", dateToString(new Date()))]
824
+
825
+ // if (user.userGroup !== "admin") {
778
826
 
779
- if (!user.viewPlacementListings || user.viewPlacementListings === "none") return;
780
- if (!user.viewAddresses || user.viewAddresses === "none") return;
781
-
782
- if (user.viewPlacementListings === "request") {
783
- if (!user.visibleListings || user.visibleListings?.length === 0) return;
784
- constraints.push(where("placementId", 'in', user.visibleListings));
785
- } else {
786
- // viewPlacementListings must be 'all'
787
-
788
- if (user.viewAddresses === "request") {
789
- if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
790
- constraints.push(where("addressId", 'in', user.visibleAddresses));
791
- }
792
- }
793
- }
794
- const toReview = await firebaseQuery.getCount("placements", constraints);
827
+ // if (!user.viewPlacementListings || user.viewPlacementListings === "none") return;
828
+ // if (!user.viewAddresses || user.viewAddresses === "none") return;
829
+
830
+ // if (user.viewPlacementListings === "request") {
831
+ // if (!user.visibleListings || user.visibleListings?.length === 0) return;
832
+ // constraints.push(where("placementId", 'in', user.visibleListings));
833
+ // } else {
834
+ // // viewPlacementListings must be 'all'
835
+
836
+ // if (user.viewAddresses === "request") {
837
+ // if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
838
+ // constraints.push(where("addressId", 'in', user.visibleAddresses));
839
+ // }
840
+ // }
841
+ // }
842
+ // const toReview = await firebaseQuery.getCount("placements", constraints);
795
843
 
796
- if (toReview === 0) return;
797
- if (toReview === 1) {
798
- const placement = Object.entries(await firebaseQuery.getDocsWhere("placements", constraints) || {})[0] as [string, StudentPlacementData];
799
- const student = await firebaseQuery.getDocData(["users", placement[1].uid]) as UserData;
800
- return {
801
- dismissible: false,
802
- severity: "primary",
803
- title: `${student.details.forename} ${student.details.surname} has completed their onboarding for their placement from ${convertDate(placement[1].startDate, "visual")} to ${convertDate(placement[1].endDate, "visual")}`,
804
- message: `Click to view the placement and review the onboarding.`,
805
- link: `/${user.product}/placements/${placement[0]}`,
806
- buttonTitle: "View",
807
- } as TaskQueryReturnObject;
808
- }
809
-
810
- return {
811
- dismissible: false,
812
- severity: "primary",
813
- title: `${toReview} student have completed their onboarding.`,
814
- message: `Click to view your placements and approve completed onboarding`,
815
- link: `/${user.product}/placementListings/placements`,
816
- buttonTitle: "View placements",
817
- } as TaskQueryReturnObject;
818
- },
819
- },
820
- uploadOnboarding: {
821
- callback: async (user) => {
844
+ // if (toReview === 0) return;
845
+ // if (toReview === 1) {
846
+ // const placement = Object.entries(await firebaseQuery.getDocsWhere("placements", constraints) || {})[0] as [string, StudentPlacementData];
847
+ // const student = await firebaseQuery.getDocData(["users", placement[1].uid]) as UserData;
848
+ // return {
849
+ // dismissible: false,
850
+ // severity: "primary",
851
+ // title: `${student.details.forename} ${student.details.surname} has completed their onboarding for their placement from ${convertDate(placement[1].startDate, "visual")} to ${convertDate(placement[1].endDate, "visual")}`,
852
+ // message: `Click to view the placement and review the onboarding.`,
853
+ // link: `/${user.product}/placements/${placement[0]}`,
854
+ // buttonTitle: "View",
855
+ // } as TaskQueryReturnObject;
856
+ // }
857
+
858
+ // return {
859
+ // dismissible: false,
860
+ // severity: "primary",
861
+ // title: `${toReview} student have completed their onboarding.`,
862
+ // message: `Click to view your placements and approve completed onboarding`,
863
+ // link: `/${user.product}/placementListings/placements`,
864
+ // buttonTitle: "View placements",
865
+ // } as TaskQueryReturnObject;
866
+ // },
867
+ // },
868
+ // uploadOnboarding: {
869
+ // callback: async (user) => {
822
870
 
823
- const constraints = [where("providerId", "==", user.oId), where("onboarding", "==", null), where("endDate", ">=", dateToString(new Date()))];
871
+ // const constraints = [where("providerId", "==", user.oId), where("onboarding", "==", null), where("endDate", ">=", dateToString(new Date()))];
824
872
 
825
873
 
826
- if (user.userGroup !== "admin") {
874
+ // if (user.userGroup !== "admin") {
827
875
 
828
- if (!user.viewPlacementListings || user.viewPlacementListings === "none") return;
829
- if (!user.viewAddresses || user.viewAddresses === "none") return;
830
-
831
- if (user.viewPlacementListings === "request") {
832
- if (!user.visibleListings || user.visibleListings?.length === 0) return;
833
- constraints.push(where("placementId", 'in', user.visibleListings));
834
- } else {
835
- // viewPlacementListings must be 'all'
836
-
837
- if (user.viewAddresses === "request") {
838
- if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
839
- constraints.push(where("addressId", 'in', user.visibleAddresses));
840
- }
841
- }
842
- }
843
-
844
- const withoutOnboarding = await firebaseQuery.getCount("placements", constraints);
845
-
846
- if (withoutOnboarding === 0) return;
847
- if (withoutOnboarding === 1) {
848
- const placement = Object.entries(await firebaseQuery.getDocsWhere("placements", constraints) || {})[0] as [string, StudentPlacementData];
849
- const student = await firebaseQuery.getDocData(["users", placement[1].uid]) as UserData;
850
- return {
851
- dismissible: false,
852
- severity: "primary",
853
- title: `Send onboarding documents to ${student.details.forename} ${student.details.surname}'s placement from ${convertDate(placement[1].startDate, "visual")} to ${convertDate(placement[1].endDate, "visual")}`,
854
- message: `Click to view the placement and add or dismiss onboarding reminders.`,
855
- link: `/${user.product}/placements/${placement[0]}`,
856
- buttonTitle: "View",
857
- } as TaskQueryReturnObject;
858
- }
859
-
860
- return {
861
- dismissible: false,
862
- severity: "primary",
863
- title: `Set up onboarding for ${withoutOnboarding} placements to prepare yourself and your students.`,
864
- message: `Click to view your placements and add or dismiss onboarding reminders.`,
865
- link: `/${user.product}/placementListings/placements`,
866
- buttonTitle: "View placements",
867
- } as TaskQueryReturnObject;
868
- },
869
- },
870
- completeListing: {
871
- callback: async (user) => {
872
- const constraints = [where("providerId", "==", user.oId), where("status", "==", "draft")];
873
-
874
-
875
- if (user.userGroup !== "admin") {
876
+ // if (!user.viewPlacementListings || user.viewPlacementListings === "none") return;
877
+ // if (!user.viewAddresses || user.viewAddresses === "none") return;
878
+
879
+ // if (user.viewPlacementListings === "request") {
880
+ // if (!user.visibleListings || user.visibleListings?.length === 0) return;
881
+ // constraints.push(where("placementId", 'in', user.visibleListings));
882
+ // } else {
883
+ // // viewPlacementListings must be 'all'
884
+
885
+ // if (user.viewAddresses === "request") {
886
+ // if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
887
+ // constraints.push(where("addressId", 'in', user.visibleAddresses));
888
+ // }
889
+ // }
890
+ // }
891
+
892
+ // const withoutOnboarding = await firebaseQuery.getCount("placements", constraints);
893
+
894
+ // if (withoutOnboarding === 0) return;
895
+ // if (withoutOnboarding === 1) {
896
+ // const placement = Object.entries(await firebaseQuery.getDocsWhere("placements", constraints) || {})[0] as [string, StudentPlacementData];
897
+ // const student = await firebaseQuery.getDocData(["users", placement[1].uid]) as UserData;
898
+ // return {
899
+ // dismissible: false,
900
+ // severity: "primary",
901
+ // title: `Send onboarding documents to ${student.details.forename} ${student.details.surname}'s placement from ${convertDate(placement[1].startDate, "visual")} to ${convertDate(placement[1].endDate, "visual")}`,
902
+ // message: `Click to view the placement and add or dismiss onboarding reminders.`,
903
+ // link: `/${user.product}/placements/${placement[0]}`,
904
+ // buttonTitle: "View",
905
+ // } as TaskQueryReturnObject;
906
+ // }
907
+
908
+ // return {
909
+ // dismissible: false,
910
+ // severity: "primary",
911
+ // title: `Set up onboarding for ${withoutOnboarding} placements to prepare yourself and your students.`,
912
+ // message: `Click to view your placements and add or dismiss onboarding reminders.`,
913
+ // link: `/${user.product}/placementListings/placements`,
914
+ // buttonTitle: "View placements",
915
+ // } as TaskQueryReturnObject;
916
+ // },
917
+ // },
918
+ // completeListing: {
919
+ // callback: async (user) => {
920
+ // const constraints = [where("providerId", "==", user.oId), where("status", "==", "draft")];
921
+
922
+
923
+ // if (user.userGroup !== "admin") {
876
924
 
877
- if (!user.viewPlacementListings || user.viewPlacementListings === "none") return;
878
- if (!user.viewAddresses || user.viewAddresses === "none") return;
879
-
880
- if (user.viewPlacementListings === "request") {
881
- if (!user.visibleListings || user.visibleListings?.length === 0) return;
882
- constraints.push(where(documentId(), 'in', user.visibleListings));
883
- } else {
884
- // viewPlacementListings must be 'all'
885
-
886
- if (user.viewAddresses === "request") {
887
- if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
888
- constraints.push(where("addressId", 'in', user.visibleAddresses));
889
- }
890
- }
891
- }
892
- const incompleteListings = await firebaseQuery.getCount("placementListings", constraints);
893
- if (incompleteListings === 0) return;
894
- if (incompleteListings === 1) {
895
- const incompleteListing = Object.entries(await firebaseQuery.getDocsWhere("placementListings", constraints) || {})[0] as [string, PlacementListing];
896
- const address = incompleteListing[1].addressId ? await firebaseQuery.getDocData(["addresses", incompleteListing[1].addressId]) as OrganisationAddress : undefined;
897
- return {
898
- dismissible: false,
899
- severity: "info",
900
- title: `Your listing '${incompleteListing[1].title || "unnamed"}' at ${address ? `${address["address-line1"]}, ${address.postal_code.toUpperCase()}, ${capitaliseWords(camelCaseToNormal(address.country))}` : "unknown address"} requires more information before publishing.`,
901
- message: `Click to complete and publish the placement listing.`,
902
- link: `/${user.product}/addListing/${incompleteListing[0]}`,
903
- buttonTitle: "View listing",
904
- } as TaskQueryReturnObject;
905
- }
906
-
907
- return {
908
- dismissible: false,
909
- severity: "info",
910
- title: `You have ${incompleteListings} draft listings waiting to be published.`,
911
- message: `Click to review and publish the placement listings.`,
912
- link: `/${user.product}/placementListings/listings`,
913
- buttonTitle: "View listings",
914
- } as TaskQueryReturnObject;
915
- },
916
- },
917
- completeAddress: {
918
- callback: async (user) => {
919
- const constraints = [where("product", "==", "providers"), where("oId", "==", user.oId), where("stage", "!=", "complete")];
920
-
921
-
922
- if (user.userGroup !== "admin") {
923
- if (!user.viewAddresses || user.viewAddresses === "none") return;
924
-
925
- if (user.viewAddresses === "request") {
926
- if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
927
- constraints.push(where("addressId", 'in', user.visibleAddresses));
928
- }
929
- }
930
- const incompleteAddresses = await firebaseQuery.getCount("addresses", constraints);
931
- if (incompleteAddresses === 0) return;
932
- if (incompleteAddresses === 1) {
933
- const address = Object.entries(await firebaseQuery.getDocsWhere("addresses", constraints) || {})[0] as [string, OrganisationAddress];
934
- return {
935
- dismissible: false,
936
- severity: "info",
937
- title: `Your address: ${address[1]["address-line1"]}, ${address[1].postal_code.toUpperCase()}, ${capitaliseWords(camelCaseToNormal(address[1].country))} is currently incomplete.`,
938
- message: `Click to complete the addresses.`,
939
- link: `/${user.product}/addAddress/${address[0]}`,
940
- buttonTitle: "View address",
941
- } as TaskQueryReturnObject;
942
- }
943
-
944
- return {
945
- dismissible: false,
946
- severity: "info",
947
- title: `You have ${incompleteAddresses} draft addresses waiting to be published.`,
948
- message: `Click to review the addresses.`,
949
- link: `/${user.product}/organisation/addresses`,
950
- buttonTitle: "View addresses",
951
- } as TaskQueryReturnObject;
952
- },
953
- },
954
- registrationRequests: {
955
- callback: async (user) => {
956
- if (!getAccess(user, "addStaff")) return;
957
-
958
- const regRequests = await firebaseQuery.getCount("requests", [where("product", "==", user.product), where("oId", "==", user.oId)]);
959
-
960
- if (regRequests === 0) return;
961
- if (regRequests === 1) {
962
- const request = Object.entries(await firebaseQuery.getDocsWhere("requests", [where("product", "==", user.product), where("oId", "==", user.oId)]) || {})[0] as [string, RegistrationRequest];
963
- return {
964
- dismissible: false,
965
- severity: "primary",
966
- title: `${request[1].forename} ${request[1].surname} has requested to access your organisation.`,
967
- message: `Click to review these request.`,
968
- link: `/${user.product}/organisation/staff/requests`,
969
- buttonTitle: "View requests",
970
- } as TaskQueryReturnObject;
971
- }
972
-
973
- return {
974
- dismissible: false,
975
- severity: "primary",
976
- title: `${regRequests} people have requested to register with your organisation.`,
977
- message: `Click to review these requests.`,
978
- link: `/${user.product}/organisation/staff/requests`,
979
- buttonTitle: "View requests",
980
- } as TaskQueryReturnObject;
981
- },
982
- },
983
- activateStaff: {
984
- callback: async (user) => {
985
- if (!getAccess(user, "addStaff")) return;
986
-
987
- const inactiveAccounts = await firebaseQuery.getCount("users", [where("product", "==", user.product), where("oId", "==", user.oId), where("status", "==", "inactive")]);
988
-
989
- if (inactiveAccounts === 0) return;
990
- if (inactiveAccounts === 1) {
991
- const account = Object.entries(await firebaseQuery.getDocsWhere("users", [where("product", "==", user.product), where("oId", "==", user.oId), where("status", "==", "inactive")]) || {})[0] as [string, UserData];
992
- return {
993
- dismissible: false,
994
- severity: "info",
995
- title: `Activate ${account[1].details.forename} ${account[1].details.surname}'s staff account.`,
996
- message: "Activate this account to give the user access to Placementt.",
997
- link: `/${user.product}/organisation/staff/all`,
998
- buttonTitle: "View accounts",
999
- } as TaskQueryReturnObject;
1000
- }
1001
-
1002
- return {
1003
- dismissible: false,
1004
- severity: "info",
1005
- title: `${inactiveAccounts} staff have inactive active accounts.`,
1006
- message: "Activate these accounts to give the user access to Placementt.",
1007
- link: `/${user.product}/organisation/staff/all`,
1008
- buttonTitle: "View accounts",
1009
- } as TaskQueryReturnObject;
1010
- },
1011
- },
1012
- placementStarting: {
1013
- callback: async (user) => {
1014
- const sevenDaysInFuture = new Date();
1015
- sevenDaysInFuture.setDate(sevenDaysInFuture.getDate() + 7)
1016
-
1017
- const constraints = [where("providerId", "==", user.oId), where("startDate", "<=", convertDate(sevenDaysInFuture, "dbstring")), where("startDate", ">", dateToString(new Date()))];
1018
-
1019
- if (user.userGroup !== "admin") {
925
+ // if (!user.viewPlacementListings || user.viewPlacementListings === "none") return;
926
+ // if (!user.viewAddresses || user.viewAddresses === "none") return;
927
+
928
+ // if (user.viewPlacementListings === "request") {
929
+ // if (!user.visibleListings || user.visibleListings?.length === 0) return;
930
+ // constraints.push(where(documentId(), 'in', user.visibleListings));
931
+ // } else {
932
+ // // viewPlacementListings must be 'all'
933
+
934
+ // if (user.viewAddresses === "request") {
935
+ // if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
936
+ // constraints.push(where("addressId", 'in', user.visibleAddresses));
937
+ // }
938
+ // }
939
+ // }
940
+ // const incompleteListings = await firebaseQuery.getCount("placementListings", constraints);
941
+ // if (incompleteListings === 0) return;
942
+ // if (incompleteListings === 1) {
943
+ // const incompleteListing = Object.entries(await firebaseQuery.getDocsWhere("placementListings", constraints) || {})[0] as [string, PlacementListing];
944
+ // const address = incompleteListing[1].addressId ? await firebaseQuery.getDocData(["addresses", incompleteListing[1].addressId]) as OrganisationAddress : undefined;
945
+ // return {
946
+ // dismissible: false,
947
+ // severity: "info",
948
+ // title: `Your listing '${incompleteListing[1].title || "unnamed"}' at ${address ? `${address["address-line1"]}, ${address.postal_code.toUpperCase()}, ${capitaliseWords(camelCaseToNormal(address.country))}` : "unknown address"} requires more information before publishing.`,
949
+ // message: `Click to complete and publish the placement listing.`,
950
+ // link: `/${user.product}/addListing/${incompleteListing[0]}`,
951
+ // buttonTitle: "View listing",
952
+ // } as TaskQueryReturnObject;
953
+ // }
954
+
955
+ // return {
956
+ // dismissible: false,
957
+ // severity: "info",
958
+ // title: `You have ${incompleteListings} draft listings waiting to be published.`,
959
+ // message: `Click to review and publish the placement listings.`,
960
+ // link: `/${user.product}/placementListings/listings`,
961
+ // buttonTitle: "View listings",
962
+ // } as TaskQueryReturnObject;
963
+ // },
964
+ // },
965
+ // completeAddress: {
966
+ // callback: async (user) => {
967
+ // const constraints = [where("product", "==", "providers"), where("oId", "==", user.oId), where("stage", "!=", "complete")];
968
+
969
+
970
+ // if (user.userGroup !== "admin") {
971
+ // if (!user.viewAddresses || user.viewAddresses === "none") return;
972
+
973
+ // if (user.viewAddresses === "request") {
974
+ // if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
975
+ // constraints.push(where("addressId", 'in', user.visibleAddresses));
976
+ // }
977
+ // }
978
+ // const incompleteAddresses = await firebaseQuery.getCount("addresses", constraints);
979
+ // if (incompleteAddresses === 0) return;
980
+ // if (incompleteAddresses === 1) {
981
+ // const address = Object.entries(await firebaseQuery.getDocsWhere("addresses", constraints) || {})[0] as [string, OrganisationAddress];
982
+ // return {
983
+ // dismissible: false,
984
+ // severity: "info",
985
+ // title: `Your address: ${address[1]["address-line1"]}, ${address[1].postal_code.toUpperCase()}, ${capitaliseWords(camelCaseToNormal(address[1].country))} is currently incomplete.`,
986
+ // message: `Click to complete the addresses.`,
987
+ // link: `/${user.product}/addAddress/${address[0]}`,
988
+ // buttonTitle: "View address",
989
+ // } as TaskQueryReturnObject;
990
+ // }
991
+
992
+ // return {
993
+ // dismissible: false,
994
+ // severity: "info",
995
+ // title: `You have ${incompleteAddresses} draft addresses waiting to be published.`,
996
+ // message: `Click to review the addresses.`,
997
+ // link: `/${user.product}/organisation/addresses`,
998
+ // buttonTitle: "View addresses",
999
+ // } as TaskQueryReturnObject;
1000
+ // },
1001
+ // },
1002
+ // registrationRequests: {
1003
+ // callback: async (user) => {
1004
+ // if (!getAccess(user, "addStaff")) return;
1005
+
1006
+ // const regRequests = await firebaseQuery.getCount("requests", [where("product", "==", user.product), where("oId", "==", user.oId)]);
1007
+
1008
+ // if (regRequests === 0) return;
1009
+ // if (regRequests === 1) {
1010
+ // const request = Object.entries(await firebaseQuery.getDocsWhere("requests", [where("product", "==", user.product), where("oId", "==", user.oId)]) || {})[0] as [string, RegistrationRequest];
1011
+ // return {
1012
+ // dismissible: false,
1013
+ // severity: "primary",
1014
+ // title: `${request[1].forename} ${request[1].surname} has requested to access your organisation.`,
1015
+ // message: `Click to review these request.`,
1016
+ // link: `/${user.product}/organisation/staff/requests`,
1017
+ // buttonTitle: "View requests",
1018
+ // } as TaskQueryReturnObject;
1019
+ // }
1020
+
1021
+ // return {
1022
+ // dismissible: false,
1023
+ // severity: "primary",
1024
+ // title: `${regRequests} people have requested to register with your organisation.`,
1025
+ // message: `Click to review these requests.`,
1026
+ // link: `/${user.product}/organisation/staff/requests`,
1027
+ // buttonTitle: "View requests",
1028
+ // } as TaskQueryReturnObject;
1029
+ // },
1030
+ // },
1031
+ // activateStaff: {
1032
+ // callback: async (user) => {
1033
+ // if (!getAccess(user, "addStaff")) return;
1034
+
1035
+ // const inactiveAccounts = await firebaseQuery.getCount("users", [where("product", "==", user.product), where("oId", "==", user.oId), where("status", "==", "inactive")]);
1036
+
1037
+ // if (inactiveAccounts === 0) return;
1038
+ // if (inactiveAccounts === 1) {
1039
+ // const account = Object.entries(await firebaseQuery.getDocsWhere("users", [where("product", "==", user.product), where("oId", "==", user.oId), where("status", "==", "inactive")]) || {})[0] as [string, UserData];
1040
+ // return {
1041
+ // dismissible: false,
1042
+ // severity: "info",
1043
+ // title: `Activate ${account[1].details.forename} ${account[1].details.surname}'s staff account.`,
1044
+ // message: "Activate this account to give the user access to Placementt.",
1045
+ // link: `/${user.product}/organisation/staff/all`,
1046
+ // buttonTitle: "View accounts",
1047
+ // } as TaskQueryReturnObject;
1048
+ // }
1049
+
1050
+ // return {
1051
+ // dismissible: false,
1052
+ // severity: "info",
1053
+ // title: `${inactiveAccounts} staff have inactive active accounts.`,
1054
+ // message: "Activate these accounts to give the user access to Placementt.",
1055
+ // link: `/${user.product}/organisation/staff/all`,
1056
+ // buttonTitle: "View accounts",
1057
+ // } as TaskQueryReturnObject;
1058
+ // },
1059
+ // },
1060
+ // placementStarting: {
1061
+ // callback: async (user) => {
1062
+ // const sevenDaysInFuture = new Date();
1063
+ // sevenDaysInFuture.setDate(sevenDaysInFuture.getDate() + 7)
1064
+
1065
+ // const constraints = [where("providerId", "==", user.oId), where("startDate", "<=", convertDate(sevenDaysInFuture, "dbstring")), where("startDate", ">", dateToString(new Date()))];
1066
+
1067
+ // if (user.userGroup !== "admin") {
1020
1068
 
1021
- if (!user.viewPlacementListings || user.viewPlacementListings === "none") return;
1022
- if (!user.viewAddresses || user.viewAddresses === "none") return;
1023
-
1024
- if (user.viewPlacementListings === "request") {
1025
- if (!user.visibleListings || user.visibleListings?.length === 0) return;
1026
- constraints.push(where(documentId(), 'in', user.visibleListings));
1027
- } else {
1028
- // viewPlacementListings must be 'all'
1029
-
1030
- if (user.viewAddresses === "request") {
1031
- if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
1032
- constraints.push(where("addressId", 'in', user.visibleAddresses));
1033
- }
1034
- }
1035
- }
1036
- const placementsStartingSoon = await firebaseQuery.getCount("placements", constraints);
1069
+ // if (!user.viewPlacementListings || user.viewPlacementListings === "none") return;
1070
+ // if (!user.viewAddresses || user.viewAddresses === "none") return;
1071
+
1072
+ // if (user.viewPlacementListings === "request") {
1073
+ // if (!user.visibleListings || user.visibleListings?.length === 0) return;
1074
+ // constraints.push(where(documentId(), 'in', user.visibleListings));
1075
+ // } else {
1076
+ // // viewPlacementListings must be 'all'
1077
+
1078
+ // if (user.viewAddresses === "request") {
1079
+ // if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
1080
+ // constraints.push(where("addressId", 'in', user.visibleAddresses));
1081
+ // }
1082
+ // }
1083
+ // }
1084
+ // const placementsStartingSoon = await firebaseQuery.getCount("placements", constraints);
1037
1085
 
1038
- if (placementsStartingSoon === 0) return;
1039
- if (placementsStartingSoon === 1) {
1040
- const placement = Object.entries(await firebaseQuery.getDocsWhere("placements", constraints) || {})[0] as [string, StudentPlacementData];
1041
- const student = placement[1].uid ? await firebaseQuery.getDocData(["users", placement[1].uid]) as UserData : {
1042
- details: {
1043
- forename: placement[1].studentForename,
1044
- surname: placement[1].studentSurname,
1045
- }
1046
- };
1047
- return {
1048
- dismissible: false,
1049
- severity: "success",
1050
- title: `${student.details.forename} ${student.details.surname}'s placement from ${convertDate(placement[1].startDate, "visual")} to ${convertDate(placement[1].endDate, "visual")} is starting in less than a week.`,
1051
- message: `Click to view the placement and acquaint yourself with the student.`,
1052
- link: `/${user.product}/placements/${placement[0]}`,
1053
- buttonTitle: "View",
1054
- } as TaskQueryReturnObject;
1055
- }
1056
-
1057
- return {
1058
- dismissible: false,
1059
- severity: "success",
1060
- title: `${placementsStartingSoon} placements starting soon.`,
1061
- message: `Click to view scheduled placements.`,
1062
- link: `/${user.product}/placementListings/placements`,
1063
- buttonTitle: "View placements",
1064
- } as TaskQueryReturnObject;
1065
- },
1066
- },
1067
- completeFeedback: {
1068
- callback: async (user) => {
1069
- return;
1070
- return {} as TaskQueryReturnObject;
1071
- },
1072
- },
1073
- setUpFeedback: {
1074
- callback: async (user) => {
1075
- return;
1076
- return {} as TaskQueryReturnObject;
1077
- },
1078
- },
1079
- }
1086
+ // if (placementsStartingSoon === 0) return;
1087
+ // if (placementsStartingSoon === 1) {
1088
+ // const placement = Object.entries(await firebaseQuery.getDocsWhere("placements", constraints) || {})[0] as [string, StudentPlacementData];
1089
+ // const student = placement[1].uid ? await firebaseQuery.getDocData(["users", placement[1].uid]) as UserData : {
1090
+ // details: {
1091
+ // forename: placement[1].studentForename,
1092
+ // surname: placement[1].studentSurname,
1093
+ // }
1094
+ // };
1095
+ // return {
1096
+ // dismissible: false,
1097
+ // severity: "success",
1098
+ // title: `${student.details.forename} ${student.details.surname}'s placement from ${convertDate(placement[1].startDate, "visual")} to ${convertDate(placement[1].endDate, "visual")} is starting in less than a week.`,
1099
+ // message: `Click to view the placement and acquaint yourself with the student.`,
1100
+ // link: `/${user.product}/placements/${placement[0]}`,
1101
+ // buttonTitle: "View",
1102
+ // } as TaskQueryReturnObject;
1103
+ // }
1104
+
1105
+ // return {
1106
+ // dismissible: false,
1107
+ // severity: "success",
1108
+ // title: `${placementsStartingSoon} placements starting soon.`,
1109
+ // message: `Click to view scheduled placements.`,
1110
+ // link: `/${user.product}/placementListings/placements`,
1111
+ // buttonTitle: "View placements",
1112
+ // } as TaskQueryReturnObject;
1113
+ // },
1114
+ // },
1115
+ // completeFeedback: {
1116
+ // callback: async (user) => {
1117
+ // return;
1118
+ // return {} as TaskQueryReturnObject;
1119
+ // },
1120
+ // },
1121
+ // setUpFeedback: {
1122
+ // callback: async (user) => {
1123
+ // return;
1124
+ // return {} as TaskQueryReturnObject;
1125
+ // },
1126
+ // },
1127
+ // }
1080
1128
 
1081
1129
  export const getTips = async (user: UserData, organisation: InstituteData|ProviderData, addresses?: {[key: string]: OrganisationAddress}):Promise<(TaskQueryReturnObject)[]> => {
1082
1130
  const tipsObject = {
@@ -1106,17 +1154,17 @@ export const getTips = async (user: UserData, organisation: InstituteData|Provid
1106
1154
  return processedTips;
1107
1155
  }
1108
1156
 
1109
- export const getTasks = async (user: UserData, organisation?: InstituteData|ProviderData, cohort?: CohortData):Promise<(TaskQueryReturnObject)[]> => {
1157
+ export const getTasks = async ({user, organisation, cohort, school}:{user: UserData, organisation?: InstituteData&ProviderData, cohort?: CohortData, school?: SchoolData}):Promise<(TaskQueryReturnObject)[]> => {
1110
1158
  // Cohort is either a specific one or all.
1111
1159
 
1112
1160
  if (user.product === "institutes" && user.userType === "Staff" && organisation) {
1113
- return await getInstituteTasks(user, organisation, cohort);
1161
+ return await getInstituteTasks({user, organisation, cohort, school});
1114
1162
  }
1115
1163
  if (user.product === "students" || user.userType === "Students") {
1116
1164
  return await getStudentTasks(user, organisation, cohort);
1117
1165
  }
1118
1166
  if (user.product === "providers" && organisation) {
1119
- return await getProviderTasks(user, organisation);
1167
+ // return await getProviderTasks(user, organisation);
1120
1168
  }
1121
1169
 
1122
1170
  return [];
@@ -1137,49 +1185,59 @@ const getStudentTasks = async (user: UserData, organisation?: InstituteData|Prov
1137
1185
  return processedTasks;
1138
1186
  };
1139
1187
 
1140
- const getProviderTasks = async (user: UserData, organisation: InstituteData|ProviderData, cohort?: CohortData):Promise<(TaskQueryReturnObject)[]> => {
1141
- const processedTasks = await Object.entries(providerTasks).reduce(async (acc, [itemName, item]) => {
1188
+ // const getProviderTasks = async (user: UserData, organisation: InstituteData|ProviderData, cohort?: CohortData):Promise<(TaskQueryReturnObject)[]> => {
1189
+ // const processedTasks = await Object.entries(providerTasks).reduce(async (acc, [itemName, item]) => {
1142
1190
 
1143
- const queryResult = await item.callback(user);
1144
- if (!queryResult) return await acc;
1191
+ // const queryResult = await item.callback(user);
1192
+ // if (!queryResult) return await acc;
1145
1193
 
1146
- const queryResultArray = Array.isArray(queryResult) ? queryResult : [queryResult];
1147
- const results = queryResultArray.map((r) => ({itemName: itemName as ProviderTaskNames, ...r}));
1194
+ // const queryResultArray = Array.isArray(queryResult) ? queryResult : [queryResult];
1195
+ // const results = queryResultArray.map((r) => ({itemName: itemName as ProviderTaskNames, ...r}));
1148
1196
 
1149
- (await acc).push(...results);
1150
- return await acc;
1151
- }, Promise.resolve<TaskQueryReturnObject[]>([]));
1152
- return processedTasks;};
1197
+ // (await acc).push(...results);
1198
+ // return await acc;
1199
+ // }, Promise.resolve<TaskQueryReturnObject[]>([]));
1200
+ // return processedTasks;};
1153
1201
 
1154
- const getInstituteTasks = async (user: UserData, organisation: InstituteData|ProviderData, cohort?: CohortData):Promise<(TaskQueryReturnObject)[]> => {
1202
+ const getInstituteTasks = async ({user, organisation, cohort, school}:{user: UserData, organisation: InstituteData&ProviderData, cohort?: CohortData, school?: SchoolData}):Promise<(TaskQueryReturnObject)[]> => {
1155
1203
  let fCohort:CohortData|[string, CohortData][]|undefined = cohort;
1156
-
1157
- if (!fCohort) {
1158
- // get all associated cohorts.
1159
- if (user.viewCohorts === "none") return([]);
1160
- if (user.userGroup === "admin" || user.viewCohorts === "all") {
1161
- const cohorts = await firebaseQuery.getDocsWhere("cohorts", [where("product", "==", user.product), where("oId", "==", user.oId), where("stage", "==", "created")]) as {[key:string]: CohortData};
1162
- fCohort = Object.entries(cohorts);
1204
+ let fSchool:SchoolData|[string, SchoolData][]|undefined = school;
1205
+
1206
+ const getCohortsOrSchoolsIfNotProvided = async (type: "cohorts"|"schools") => {
1207
+ if (user[`view${type}`] === "none") return([]);
1208
+ if (user.userGroup === "admin" || user[`view${type}`] === "all") {
1209
+ const constraints = [where("oId", "==", user.oId)];
1210
+ if (type === "cohorts") {
1211
+ constraints.push(where("product", "==", user.product), where("stage", "==", "created"));
1212
+ }
1213
+ const cohorts = await firebaseQuery.getDocsWhere(type, constraints) as {[key:string]: CohortData|SchoolData};
1214
+ return Object.entries(cohorts);
1163
1215
  }
1164
- if (user.viewCohorts === "some") {
1165
- const cohorts = await user.visibleCohorts?.reduce(async (acc, cohortId) => {
1166
- const cohort = await firebaseQuery.getDocData(["cohorts", cohortId]) as CohortData;
1167
- if (cohort.stage !== "created") {
1216
+ if (user[`view${type}`] === "some") {
1217
+ const items = await user[`visible${type}s`]?.reduce(async (acc, itemId) => {
1218
+ const item = await firebaseQuery.getDocData([type, itemId]) as CohortData;
1219
+ if (type === "cohorts" && item.stage !== "created") {
1168
1220
  return acc;
1169
1221
  }
1170
- acc[cohortId] = cohort;
1222
+ acc[itemId] = item;
1171
1223
  return acc;
1172
1224
  }, Promise.resolve<[string, CohortData][]>([]));
1173
- fCohort = cohorts;
1225
+ return items;
1174
1226
  }
1175
1227
  }
1176
-
1228
+
1229
+ if (!fCohort) {
1230
+ fCohort = await getCohortsOrSchoolsIfNotProvided("cohorts");
1231
+ }
1232
+ if (!fSchool) {
1233
+ fSchool = await getCohortsOrSchoolsIfNotProvided("schools");
1234
+ }
1177
1235
  const processedTasks = await Object.entries(instituteTasks).reduce(async (acc, [itemName, item]) => {
1178
1236
  if (!fCohort) {
1179
1237
  console.log("No cohorts to retrieve tasks for");
1180
1238
  return([]);
1181
1239
  }
1182
- const queryResult = await item.callback(user, organisation, fCohort);
1240
+ const queryResult = await item.callback({user, organisation, cohorts: fCohort, schools: fSchool});
1183
1241
  if (!queryResult) return await acc;
1184
1242
 
1185
1243
  const queryResultArray = Array.isArray(queryResult) ? queryResult : [queryResult];