placementt-core 1.20.232 → 1.300.4

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 (101) hide show
  1. package/.eslintrc.js +40 -40
  2. package/.gitattributes +2 -2
  3. package/deploy-all.js +75 -0
  4. package/lib/config.d.ts +0 -13
  5. package/lib/config.js +1 -3
  6. package/lib/config.js.map +1 -1
  7. package/lib/constants.d.ts +1 -0
  8. package/lib/constants.js +48 -1
  9. package/lib/constants.js.map +1 -1
  10. package/lib/features/config.d.ts +133 -133
  11. package/lib/features/config.js +35 -35
  12. package/lib/features/contacts/contacts.d.ts +75 -75
  13. package/lib/features/contacts/contacts.js +105 -105
  14. package/lib/features/downtime/useDowntime.d.ts +11 -11
  15. package/lib/features/downtime/useDowntime.js +22 -22
  16. package/lib/features/placements/studentPlacements/activePlacement.js +1 -1
  17. package/lib/features/placements/studentPlacements/activePlacement.js.map +1 -1
  18. package/lib/features/placements/studentPlacements/studentPlacementsSlice.d.ts +63 -63
  19. package/lib/features/placements/studentPlacements/studentPlacementsSlice.js +81 -81
  20. package/lib/features/providerPlacements/providerPlacementsSlice.d.ts +19 -19
  21. package/lib/features/providerPlacements/providerPlacementsSlice.js +24 -24
  22. package/lib/features/studentPlacements/studentPlacementsSlice.d.ts +62 -62
  23. package/lib/features/studentPlacements/studentPlacementsSlice.js +87 -87
  24. package/lib/features/studentPlacements/useStudentPlacements.d.ts +6 -6
  25. package/lib/features/studentPlacements/useStudentPlacements.js +18 -18
  26. package/lib/features/userSlice.d.ts +26 -26
  27. package/lib/features/userSlice.js +23 -23
  28. package/lib/features/users/useUserFunctions.d.ts +25 -25
  29. package/lib/features/users/useUserFunctions.js +124 -124
  30. package/lib/features/users/userSlice.d.ts +46 -46
  31. package/lib/features/users/userSlice.js +48 -48
  32. package/lib/firebase/firebase.d.ts +1 -1
  33. package/lib/firebase/firebase.js +8 -3
  34. package/lib/firebase/firebase.js.map +1 -1
  35. package/lib/firebase/firebaseConfig.js +1 -0
  36. package/lib/firebase/firebaseConfig.js.map +1 -1
  37. package/lib/firebase/readDatabase.js +7 -7
  38. package/lib/firebase/readDatabase.js.map +1 -1
  39. package/lib/hooks.d.ts +85 -192
  40. package/lib/hooks.js +731 -671
  41. package/lib/hooks.js.map +1 -1
  42. package/lib/images/GatsbyBenchmarks.d.ts +1 -2
  43. package/lib/index.d.ts +0 -1
  44. package/lib/index.js +0 -1
  45. package/lib/index.js.map +1 -1
  46. package/lib/reduxHooks.d.ts +9 -41
  47. package/lib/reduxHooks.js +1 -49
  48. package/lib/reduxHooks.js.map +1 -1
  49. package/lib/tasksAndTips.js +368 -418
  50. package/lib/tasksAndTips.js.map +1 -1
  51. package/lib/typeDefinitions.d.ts +162 -83
  52. package/lib/util.d.ts +25 -1
  53. package/lib/util.js +329 -2
  54. package/lib/util.js.map +1 -1
  55. package/package.json +56 -56
  56. package/src/DatabaseDefinitions.ts +18 -18
  57. package/src/apiCalls.ts +128 -128
  58. package/src/config.ts +50 -53
  59. package/src/constants.ts +846 -796
  60. package/src/databaseTypes.ts +42 -42
  61. package/src/features/analytics/useAnalytics.tsx +63 -63
  62. package/src/features/contacts/contactsSlice.ts +147 -147
  63. package/src/features/contacts/useContacts.tsx +73 -73
  64. package/src/features/dropdown/useDropdown.tsx +52 -52
  65. package/src/features/global/downtime/useDowntime.tsx +23 -23
  66. package/src/features/global/users/useUserFunctions.tsx +132 -132
  67. package/src/features/jobs/jobsSlice.ts +71 -71
  68. package/src/features/placements/studentPlacements/activePlacement.ts +68 -68
  69. package/src/features/placements/studentPlacements/completedStudentPlacementsSlice.ts +97 -97
  70. package/src/features/placements/studentPlacements/upcomingStudentPlacementsSlice.ts +108 -108
  71. package/src/features/placements/studentPlacements/useStudentPlacements.tsx +9 -9
  72. package/src/features/placements/types.ts +10 -10
  73. package/src/features/referrals/useReferrals.tsx +56 -56
  74. package/src/features/updates/useUpdates.tsx +38 -38
  75. package/src/firebase/firebase.tsx +158 -153
  76. package/src/firebase/firebaseConfig.tsx +47 -45
  77. package/src/firebase/firebaseQuery.tsx +151 -151
  78. package/src/firebase/persistence.ts +84 -84
  79. package/src/firebase/readDatabase.tsx +236 -236
  80. package/src/firebase/util.tsx +352 -352
  81. package/src/firebase/writeDatabase.tsx +77 -77
  82. package/src/hooks.tsx +4476 -4463
  83. package/src/images/GatsbyBenchmarks.tsx +711 -711
  84. package/src/images/LogFuturePlacement.jsx +64 -64
  85. package/src/images/LogPreviousPlacement.jsx +228 -228
  86. package/src/images/gatsby_benchmarks.svg +466 -466
  87. package/src/images/log_future_placement.svg +114 -114
  88. package/src/images/log_previous_placement.svg +199 -199
  89. package/src/index.ts +34 -35
  90. package/src/readDatabase.tsx +3 -3
  91. package/src/reduxHooks.ts +295 -352
  92. package/src/tasksAndTips.ts +1267 -1267
  93. package/src/tutorialTips.ts +58 -58
  94. package/src/typeDefinitions.ts +1260 -1129
  95. package/src/util.ts +523 -177
  96. package/tsconfig.dev.json +5 -5
  97. package/tsconfig.json +21 -21
  98. package/lib/features/logs/logsSlice.d.ts +0 -93
  99. package/lib/features/logs/logsSlice.js +0 -146
  100. package/lib/features/logs/logsSlice.js.map +0 -1
  101. package/src/features/logs/logsSlice.ts +0 -208
@@ -670,411 +670,363 @@ const studentTasks = {
670
670
  },
671
671
  }
672
672
  };
673
- const providerTasks = {
674
- requestedVisibleAddresses: {
675
- callback: async (user) => {
676
- if (!(0, util_1.getAccess)(user, "addStaff"))
677
- return;
678
- const accessRequests = await firebaseQuery.getCount("users", [(0, firestore_1.where)("oId", "==", user.oId), (0, firestore_1.where)("product", "==", "providers"), (0, firestore_1.orderBy)("requestedVisibleAddresses")]) - ((Array.isArray(user === null || user === void 0 ? void 0 : user.requestedVisibleAddresses) && (user === null || user === void 0 ? void 0 : user.requestedVisibleAddresses.length) > 0) ? 1 : 0);
679
- if (accessRequests === 0)
680
- return;
681
- if (accessRequests === 1) {
682
- const userRequestingAccess = Object.entries(await firebaseQuery.getDocsWhere("users", [(0, firestore_1.where)("product", "==", "providers"), (0, firestore_1.where)("oId", "==", user.oId), (0, firestore_1.orderBy)("requestedVisibleAddresses")]) || {})[0];
683
- return {
684
- dismissible: false,
685
- severity: "primary",
686
- title: `${userRequestingAccess[1].details.forename} ${userRequestingAccess[1].details.surname} has requested access to view addresses.`,
687
- message: `Click to review the addresses and grant access to the user.`,
688
- link: `/${user.product}/users/${userRequestingAccess[0]}`,
689
- buttonTitle: "View request",
690
- };
691
- }
692
- return {
693
- dismissible: false,
694
- severity: "warning",
695
- title: `Multiple users have requested access to view addresses.`,
696
- message: `Click to review the addresses and grant access to the user.`,
697
- link: `/${user.product}/organisation/staff/all`,
698
- buttonTitle: "View request",
699
- };
700
- },
701
- },
702
- requestedVisiblePlacementListings: {
703
- callback: async (user) => {
704
- if (!(0, util_1.getAccess)(user, "addStaff"))
705
- return;
706
- const accessRequests = await firebaseQuery.getCount("users", [(0, firestore_1.where)("oId", "==", user.oId), (0, firestore_1.where)("product", "==", "providers"), (0, firestore_1.orderBy)("requestedVisibleListings")]) - ((Array.isArray(user === null || user === void 0 ? void 0 : user.requestedVisibleListings) && (user === null || user === void 0 ? void 0 : user.requestedVisibleListings.length) > 0) ? 1 : 0);
707
- ;
708
- if (accessRequests === 0)
709
- return;
710
- if (accessRequests === 1) {
711
- const userRequestingAccess = Object.entries(await firebaseQuery.getDocsWhere("users", [(0, firestore_1.where)("oId", "==", user.oId), (0, firestore_1.where)("product", "==", "providers"), (0, firestore_1.orderBy)("requestedVisibleListings")]) || {})[0];
712
- return {
713
- dismissible: false,
714
- severity: "primary",
715
- title: `${userRequestingAccess[1].details.forename} ${userRequestingAccess[1].details.surname} has requested access to view placement listings.`,
716
- message: `Click to review the placement listings and grant access to the user.`,
717
- link: `/${user.product}/users/${userRequestingAccess[0]}`,
718
- buttonTitle: "View request",
719
- };
720
- }
721
- return {
722
- dismissible: false,
723
- severity: "warning",
724
- title: `Multiple users have requested access to view placement listings.`,
725
- message: `Click to review the placement listings and grant access to the user.`,
726
- link: `/${user.product}/organisation/staff/all`,
727
- buttonTitle: "View request",
728
- };
729
- },
730
- },
731
- applicationRequireReview: {
732
- callback: async (user) => {
733
- var _a, _b;
734
- const constraints = [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.where)("reqUserType", "==", "Staff"), (0, firestore_1.where)("status", "==", "submitted")];
735
- if (user.userGroup !== "admin") {
736
- if (!user.viewPlacementListings || user.viewPlacementListings === "none")
737
- return;
738
- if (!user.viewAddresses || user.viewAddresses === "none")
739
- return;
740
- if (user.viewPlacementListings === "request") {
741
- if (!user.visibleListings || ((_a = user.visibleListings) === null || _a === void 0 ? void 0 : _a.length) === 0)
742
- return;
743
- constraints.push((0, firestore_1.where)("listingId", 'in', user.visibleListings));
744
- }
745
- else {
746
- // viewPlacementListings must be 'all'
747
- if (user.viewAddresses === "request") {
748
- if (!user.visibleAddresses || ((_b = user.visibleAddresses) === null || _b === void 0 ? void 0 : _b.length) === 0)
749
- return;
750
- constraints.push((0, firestore_1.where)("addressId", 'in', user.visibleAddresses));
751
- }
752
- }
753
- }
754
- const applicationCount = await firebaseQuery.getCount("applications", constraints);
755
- if (applicationCount === 0)
756
- return;
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
- };
765
- },
766
- },
767
- completeStudentDocs: {
768
- callback: async (user) => {
769
- return;
770
- return {};
771
- },
772
- },
773
- reviewOnboarding: {
774
- callback: async (user) => {
775
- var _a, _b;
776
- const constraints = [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.where)("onboarding.completed.accepted", "==", false), (0, firestore_1.where)("onboarding.completed.submitted", "==", true), (0, firestore_1.where)("endDate", ">=", (0, util_1.dateToString)(new Date()))];
777
- if (user.userGroup !== "admin") {
778
- if (!user.viewPlacementListings || user.viewPlacementListings === "none")
779
- return;
780
- if (!user.viewAddresses || user.viewAddresses === "none")
781
- return;
782
- if (user.viewPlacementListings === "request") {
783
- if (!user.visibleListings || ((_a = user.visibleListings) === null || _a === void 0 ? void 0 : _a.length) === 0)
784
- return;
785
- constraints.push((0, firestore_1.where)("placementId", 'in', user.visibleListings));
786
- }
787
- else {
788
- // viewPlacementListings must be 'all'
789
- if (user.viewAddresses === "request") {
790
- if (!user.visibleAddresses || ((_b = user.visibleAddresses) === null || _b === void 0 ? void 0 : _b.length) === 0)
791
- return;
792
- constraints.push((0, firestore_1.where)("addressId", 'in', user.visibleAddresses));
793
- }
794
- }
795
- }
796
- const toReview = await firebaseQuery.getCount("placements", constraints);
797
- if (toReview === 0)
798
- return;
799
- if (toReview === 1) {
800
- const placement = Object.entries(await firebaseQuery.getDocsWhere("placements", constraints) || {})[0];
801
- const student = await firebaseQuery.getDocData(["users", placement[1].uid]);
802
- return {
803
- dismissible: false,
804
- severity: "primary",
805
- title: `${student.details.forename} ${student.details.surname} has completed their onboarding for their placement from ${(0, util_2.convertDate)(placement[1].startDate, "visual")} to ${(0, util_2.convertDate)(placement[1].endDate, "visual")}`,
806
- message: `Click to view the placement and review the onboarding.`,
807
- link: `/${user.product}/placements/${placement[0]}`,
808
- buttonTitle: "View",
809
- };
810
- }
811
- return {
812
- dismissible: false,
813
- severity: "primary",
814
- title: `${toReview} student have completed their onboarding.`,
815
- message: `Click to view your placements and approve completed onboarding`,
816
- link: `/${user.product}/placementListings/placements`,
817
- buttonTitle: "View placements",
818
- };
819
- },
820
- },
821
- uploadOnboarding: {
822
- callback: async (user) => {
823
- var _a, _b;
824
- const constraints = [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.where)("onboarding", "==", null), (0, firestore_1.where)("endDate", ">=", (0, util_1.dateToString)(new Date()))];
825
- if (user.userGroup !== "admin") {
826
- if (!user.viewPlacementListings || user.viewPlacementListings === "none")
827
- return;
828
- if (!user.viewAddresses || user.viewAddresses === "none")
829
- return;
830
- if (user.viewPlacementListings === "request") {
831
- if (!user.visibleListings || ((_a = user.visibleListings) === null || _a === void 0 ? void 0 : _a.length) === 0)
832
- return;
833
- constraints.push((0, firestore_1.where)("placementId", 'in', user.visibleListings));
834
- }
835
- else {
836
- // viewPlacementListings must be 'all'
837
- if (user.viewAddresses === "request") {
838
- if (!user.visibleAddresses || ((_b = user.visibleAddresses) === null || _b === void 0 ? void 0 : _b.length) === 0)
839
- return;
840
- constraints.push((0, firestore_1.where)("addressId", 'in', user.visibleAddresses));
841
- }
842
- }
843
- }
844
- const withoutOnboarding = await firebaseQuery.getCount("placements", constraints);
845
- if (withoutOnboarding === 0)
846
- return;
847
- if (withoutOnboarding === 1) {
848
- const placement = Object.entries(await firebaseQuery.getDocsWhere("placements", constraints) || {})[0];
849
- const student = await firebaseQuery.getDocData(["users", placement[1].uid]);
850
- return {
851
- dismissible: false,
852
- severity: "primary",
853
- title: `Send onboarding documents to ${student.details.forename} ${student.details.surname}'s placement from ${(0, util_2.convertDate)(placement[1].startDate, "visual")} to ${(0, util_2.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
- };
858
- }
859
- return {
860
- dismissible: false,
861
- severity: "primary",
862
- title: `Set up onboarding for ${withoutOnboarding} placements to prepare yourself and your students.`,
863
- message: `Click to view your placements and add or dismiss onboarding reminders.`,
864
- link: `/${user.product}/placementListings/placements`,
865
- buttonTitle: "View placements",
866
- };
867
- },
868
- },
869
- completeListing: {
870
- callback: async (user) => {
871
- var _a, _b;
872
- const constraints = [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.where)("status", "==", "draft")];
873
- if (user.userGroup !== "admin") {
874
- if (!user.viewPlacementListings || user.viewPlacementListings === "none")
875
- return;
876
- if (!user.viewAddresses || user.viewAddresses === "none")
877
- return;
878
- if (user.viewPlacementListings === "request") {
879
- if (!user.visibleListings || ((_a = user.visibleListings) === null || _a === void 0 ? void 0 : _a.length) === 0)
880
- return;
881
- constraints.push((0, firestore_1.where)((0, firestore_1.documentId)(), 'in', user.visibleListings));
882
- }
883
- else {
884
- // viewPlacementListings must be 'all'
885
- if (user.viewAddresses === "request") {
886
- if (!user.visibleAddresses || ((_b = user.visibleAddresses) === null || _b === void 0 ? void 0 : _b.length) === 0)
887
- return;
888
- constraints.push((0, firestore_1.where)("addressId", 'in', user.visibleAddresses));
889
- }
890
- }
891
- }
892
- const incompleteListings = await firebaseQuery.getCount("placementListings", constraints);
893
- if (incompleteListings === 0)
894
- return;
895
- if (incompleteListings === 1) {
896
- const incompleteListing = Object.entries(await firebaseQuery.getDocsWhere("placementListings", constraints) || {})[0];
897
- const address = incompleteListing[1].addressId ? await firebaseQuery.getDocData(["addresses", incompleteListing[1].addressId]) : undefined;
898
- return {
899
- dismissible: false,
900
- severity: "info",
901
- title: `Your listing '${incompleteListing[1].title || "unnamed"}' at ${address ? `${address["address-line1"]}, ${address.postal_code.toUpperCase()}, ${(0, util_1.capitaliseWords)((0, util_1.camelCaseToNormal)(address.country))}` : "unknown address"} requires more information before publishing.`,
902
- message: `Click to complete and publish the placement listing.`,
903
- link: `/${user.product}/addListing/${incompleteListing[0]}`,
904
- buttonTitle: "View listing",
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
- };
915
- },
916
- },
917
- completeAddress: {
918
- callback: async (user) => {
919
- var _a;
920
- const constraints = [(0, firestore_1.where)("product", "==", "providers"), (0, firestore_1.where)("oId", "==", user.oId), (0, firestore_1.where)("stage", "!=", "complete")];
921
- if (user.userGroup !== "admin") {
922
- if (!user.viewAddresses || user.viewAddresses === "none")
923
- return;
924
- if (user.viewAddresses === "request") {
925
- if (!user.visibleAddresses || ((_a = user.visibleAddresses) === null || _a === void 0 ? void 0 : _a.length) === 0)
926
- return;
927
- constraints.push((0, firestore_1.where)("addressId", 'in', user.visibleAddresses));
928
- }
929
- }
930
- const incompleteAddresses = await firebaseQuery.getCount("addresses", constraints);
931
- if (incompleteAddresses === 0)
932
- return;
933
- if (incompleteAddresses === 1) {
934
- const address = Object.entries(await firebaseQuery.getDocsWhere("addresses", constraints) || {})[0];
935
- return {
936
- dismissible: false,
937
- severity: "info",
938
- title: `Your address: ${address[1]["address-line1"]}, ${address[1].postal_code.toUpperCase()}, ${(0, util_1.capitaliseWords)((0, util_1.camelCaseToNormal)(address[1].country))} is currently incomplete.`,
939
- message: `Click to complete the addresses.`,
940
- link: `/${user.product}/addAddress/${address[0]}`,
941
- buttonTitle: "View address",
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
- };
952
- },
953
- },
954
- registrationRequests: {
955
- callback: async (user) => {
956
- if (!(0, util_1.getAccess)(user, "addStaff"))
957
- return;
958
- const regRequests = await firebaseQuery.getCount("requests", [(0, firestore_1.where)("product", "==", user.product), (0, firestore_1.where)("oId", "==", user.oId)]);
959
- if (regRequests === 0)
960
- return;
961
- if (regRequests === 1) {
962
- const request = Object.entries(await firebaseQuery.getDocsWhere("requests", [(0, firestore_1.where)("product", "==", user.product), (0, firestore_1.where)("oId", "==", user.oId)]) || {})[0];
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
- };
971
- }
972
- return {
973
- dismissible: false,
974
- severity: "primary",
975
- title: `${regRequests} people have requested to register with your organisation.`,
976
- message: `Click to review these requests.`,
977
- link: `/${user.product}/organisation/staff/requests`,
978
- buttonTitle: "View requests",
979
- };
980
- },
981
- },
982
- activateStaff: {
983
- callback: async (user) => {
984
- if (!(0, util_1.getAccess)(user, "addStaff"))
985
- return;
986
- const inactiveAccounts = await firebaseQuery.getCount("users", [(0, firestore_1.where)("product", "==", user.product), (0, firestore_1.where)("oId", "==", user.oId), (0, firestore_1.where)("status", "==", "inactive")]);
987
- if (inactiveAccounts === 0)
988
- return;
989
- if (inactiveAccounts === 1) {
990
- const account = Object.entries(await firebaseQuery.getDocsWhere("users", [(0, firestore_1.where)("product", "==", user.product), (0, firestore_1.where)("oId", "==", user.oId), (0, firestore_1.where)("status", "==", "inactive")]) || {})[0];
991
- return {
992
- dismissible: false,
993
- severity: "info",
994
- title: `Activate ${account[1].details.forename} ${account[1].details.surname}'s staff account.`,
995
- message: "Activate this account to give the user access to Placementt.",
996
- link: `/${user.product}/organisation/staff/all`,
997
- buttonTitle: "View accounts",
998
- };
999
- }
1000
- return {
1001
- dismissible: false,
1002
- severity: "info",
1003
- title: `${inactiveAccounts} staff have inactive active accounts.`,
1004
- message: "Activate these accounts to give the user access to Placementt.",
1005
- link: `/${user.product}/organisation/staff/all`,
1006
- buttonTitle: "View accounts",
1007
- };
1008
- },
1009
- },
1010
- placementStarting: {
1011
- callback: async (user) => {
1012
- var _a, _b;
1013
- const sevenDaysInFuture = new Date();
1014
- sevenDaysInFuture.setDate(sevenDaysInFuture.getDate() + 7);
1015
- const constraints = [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.where)("startDate", "<=", (0, util_2.convertDate)(sevenDaysInFuture, "dbstring")), (0, firestore_1.where)("startDate", ">", (0, util_1.dateToString)(new Date()))];
1016
- if (user.userGroup !== "admin") {
1017
- if (!user.viewPlacementListings || user.viewPlacementListings === "none")
1018
- return;
1019
- if (!user.viewAddresses || user.viewAddresses === "none")
1020
- return;
1021
- if (user.viewPlacementListings === "request") {
1022
- if (!user.visibleListings || ((_a = user.visibleListings) === null || _a === void 0 ? void 0 : _a.length) === 0)
1023
- return;
1024
- constraints.push((0, firestore_1.where)((0, firestore_1.documentId)(), 'in', user.visibleListings));
1025
- }
1026
- else {
1027
- // viewPlacementListings must be 'all'
1028
- if (user.viewAddresses === "request") {
1029
- if (!user.visibleAddresses || ((_b = user.visibleAddresses) === null || _b === void 0 ? void 0 : _b.length) === 0)
1030
- return;
1031
- constraints.push((0, firestore_1.where)("addressId", 'in', user.visibleAddresses));
1032
- }
1033
- }
1034
- }
1035
- const placementsStartingSoon = await firebaseQuery.getCount("placements", constraints);
1036
- if (placementsStartingSoon === 0)
1037
- return;
1038
- if (placementsStartingSoon === 1) {
1039
- const placement = Object.entries(await firebaseQuery.getDocsWhere("placements", constraints) || {})[0];
1040
- const student = placement[1].uid ? await firebaseQuery.getDocData(["users", placement[1].uid]) : {
1041
- details: {
1042
- forename: placement[1].studentForename,
1043
- surname: placement[1].studentSurname,
1044
- }
1045
- };
1046
- return {
1047
- dismissible: false,
1048
- severity: "success",
1049
- title: `${student.details.forename} ${student.details.surname}'s placement from ${(0, util_2.convertDate)(placement[1].startDate, "visual")} to ${(0, util_2.convertDate)(placement[1].endDate, "visual")} is starting in less than a week.`,
1050
- message: `Click to view the placement and acquaint yourself with the student.`,
1051
- link: `/${user.product}/placements/${placement[0]}`,
1052
- buttonTitle: "View",
1053
- };
1054
- }
1055
- return {
1056
- dismissible: false,
1057
- severity: "success",
1058
- title: `${placementsStartingSoon} placements starting soon.`,
1059
- message: `Click to view scheduled placements.`,
1060
- link: `/${user.product}/placementListings/placements`,
1061
- buttonTitle: "View placements",
1062
- };
1063
- },
1064
- },
1065
- completeFeedback: {
1066
- callback: async (user) => {
1067
- return;
1068
- return {};
1069
- },
1070
- },
1071
- setUpFeedback: {
1072
- callback: async (user) => {
1073
- return;
1074
- return {};
1075
- },
1076
- },
1077
- };
673
+ // const providerTasks:ProviderTaskObject = {
674
+ // requestedVisibleAddresses: {
675
+ // callback: async (user) => {
676
+ // if (!getAccess(user, "addStaff")) return;
677
+ // 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);
678
+ // if (accessRequests === 0) return;
679
+ // if (accessRequests === 1) {
680
+ // const userRequestingAccess = Object.entries(await firebaseQuery.getDocsWhere("users", [where("product", "==", "providers"), where("oId", "==", user.oId), orderBy("requestedVisibleAddresses")]) || {})[0] as [string, UserData];
681
+ // return {
682
+ // dismissible: false,
683
+ // severity: "primary",
684
+ // title: `${userRequestingAccess[1].details.forename} ${userRequestingAccess[1].details.surname} has requested access to view addresses.`,
685
+ // message: `Click to review the addresses and grant access to the user.`,
686
+ // link: `/${user.product}/users/${userRequestingAccess[0]}`,
687
+ // buttonTitle: "View request",
688
+ // } as TaskQueryReturnObject;
689
+ // }
690
+ // return {
691
+ // dismissible: false,
692
+ // severity: "warning",
693
+ // title: `Multiple users have requested access to view addresses.`,
694
+ // message: `Click to review the addresses and grant access to the user.`,
695
+ // link: `/${user.product}/organisation/staff/all`,
696
+ // buttonTitle: "View request",
697
+ // } as TaskQueryReturnObject;
698
+ // },
699
+ // },
700
+ // requestedVisiblePlacementListings: {
701
+ // callback: async (user) => {
702
+ // if (!getAccess(user, "addStaff")) return;
703
+ // 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);;
704
+ // if (accessRequests === 0) return;
705
+ // if (accessRequests === 1) {
706
+ // const userRequestingAccess = Object.entries(await firebaseQuery.getDocsWhere("users", [where("oId", "==", user.oId), where("product", "==", "providers"), orderBy("requestedVisibleListings")]) || {})[0] as [string, UserData];
707
+ // return {
708
+ // dismissible: false,
709
+ // severity: "primary",
710
+ // title: `${userRequestingAccess[1].details.forename} ${userRequestingAccess[1].details.surname} has requested access to view placement listings.`,
711
+ // message: `Click to review the placement listings and grant access to the user.`,
712
+ // link: `/${user.product}/users/${userRequestingAccess[0]}`,
713
+ // buttonTitle: "View request",
714
+ // } as TaskQueryReturnObject;
715
+ // }
716
+ // return {
717
+ // dismissible: false,
718
+ // severity: "warning",
719
+ // title: `Multiple users have requested access to view placement listings.`,
720
+ // message: `Click to review the placement listings and grant access to the user.`,
721
+ // link: `/${user.product}/organisation/staff/all`,
722
+ // buttonTitle: "View request",
723
+ // } as TaskQueryReturnObject;
724
+ // },
725
+ // },
726
+ // applicationRequireReview: {
727
+ // callback: async (user) => {
728
+ // const constraints = [where("providerId", "==", user.oId), where("reqUserType", "==", "Staff"), where("status", "==", "submitted")];
729
+ // if (user.userGroup !== "admin") {
730
+ // if (!user.viewPlacementListings || user.viewPlacementListings === "none") return;
731
+ // if (!user.viewAddresses || user.viewAddresses === "none") return;
732
+ // if (user.viewPlacementListings === "request") {
733
+ // if (!user.visibleListings || user.visibleListings?.length === 0) return;
734
+ // constraints.push(where("listingId", 'in', user.visibleListings));
735
+ // } else {
736
+ // // viewPlacementListings must be 'all'
737
+ // if (user.viewAddresses === "request") {
738
+ // if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
739
+ // constraints.push(where("addressId", 'in', user.visibleAddresses));
740
+ // }
741
+ // }
742
+ // }
743
+ // const applicationCount = await firebaseQuery.getCount("applications", constraints);
744
+ // if (applicationCount === 0) return;
745
+ // return {
746
+ // dismissible: false,
747
+ // severity: "primary",
748
+ // title: `${applicationCount} applications require your review.`,
749
+ // message: `Click to view ${applicationCount} that require your attention.`,
750
+ // link: `/${user.product}/placementListings/applicants`,
751
+ // buttonTitle: "View applications",
752
+ // } as TaskQueryReturnObject;
753
+ // },
754
+ // },
755
+ // completeStudentDocs: {
756
+ // callback: async (user) => {
757
+ // return;
758
+ // return {} as TaskQueryReturnObject;
759
+ // },
760
+ // },
761
+ // reviewOnboarding: {
762
+ // callback: async (user) => {
763
+ // const constraints = [where("providerId", "==", user.oId), where("onboarding.completed.accepted", "==", false), where("onboarding.completed.submitted", "==", true), where("endDate", ">=", dateToString(new Date()))]
764
+ // if (user.userGroup !== "admin") {
765
+ // if (!user.viewPlacementListings || user.viewPlacementListings === "none") return;
766
+ // if (!user.viewAddresses || user.viewAddresses === "none") return;
767
+ // if (user.viewPlacementListings === "request") {
768
+ // if (!user.visibleListings || user.visibleListings?.length === 0) return;
769
+ // constraints.push(where("placementId", 'in', user.visibleListings));
770
+ // } else {
771
+ // // viewPlacementListings must be 'all'
772
+ // if (user.viewAddresses === "request") {
773
+ // if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
774
+ // constraints.push(where("addressId", 'in', user.visibleAddresses));
775
+ // }
776
+ // }
777
+ // }
778
+ // const toReview = await firebaseQuery.getCount("placements", constraints);
779
+ // if (toReview === 0) return;
780
+ // if (toReview === 1) {
781
+ // const placement = Object.entries(await firebaseQuery.getDocsWhere("placements", constraints) || {})[0] as [string, StudentPlacementData];
782
+ // const student = await firebaseQuery.getDocData(["users", placement[1].uid]) as UserData;
783
+ // return {
784
+ // dismissible: false,
785
+ // severity: "primary",
786
+ // 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")}`,
787
+ // message: `Click to view the placement and review the onboarding.`,
788
+ // link: `/${user.product}/placements/${placement[0]}`,
789
+ // buttonTitle: "View",
790
+ // } as TaskQueryReturnObject;
791
+ // }
792
+ // return {
793
+ // dismissible: false,
794
+ // severity: "primary",
795
+ // title: `${toReview} student have completed their onboarding.`,
796
+ // message: `Click to view your placements and approve completed onboarding`,
797
+ // link: `/${user.product}/placementListings/placements`,
798
+ // buttonTitle: "View placements",
799
+ // } as TaskQueryReturnObject;
800
+ // },
801
+ // },
802
+ // uploadOnboarding: {
803
+ // callback: async (user) => {
804
+ // const constraints = [where("providerId", "==", user.oId), where("onboarding", "==", null), where("endDate", ">=", dateToString(new Date()))];
805
+ // if (user.userGroup !== "admin") {
806
+ // if (!user.viewPlacementListings || user.viewPlacementListings === "none") return;
807
+ // if (!user.viewAddresses || user.viewAddresses === "none") return;
808
+ // if (user.viewPlacementListings === "request") {
809
+ // if (!user.visibleListings || user.visibleListings?.length === 0) return;
810
+ // constraints.push(where("placementId", 'in', user.visibleListings));
811
+ // } else {
812
+ // // viewPlacementListings must be 'all'
813
+ // if (user.viewAddresses === "request") {
814
+ // if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
815
+ // constraints.push(where("addressId", 'in', user.visibleAddresses));
816
+ // }
817
+ // }
818
+ // }
819
+ // const withoutOnboarding = await firebaseQuery.getCount("placements", constraints);
820
+ // if (withoutOnboarding === 0) return;
821
+ // if (withoutOnboarding === 1) {
822
+ // const placement = Object.entries(await firebaseQuery.getDocsWhere("placements", constraints) || {})[0] as [string, StudentPlacementData];
823
+ // const student = await firebaseQuery.getDocData(["users", placement[1].uid]) as UserData;
824
+ // return {
825
+ // dismissible: false,
826
+ // severity: "primary",
827
+ // 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")}`,
828
+ // message: `Click to view the placement and add or dismiss onboarding reminders.`,
829
+ // link: `/${user.product}/placements/${placement[0]}`,
830
+ // buttonTitle: "View",
831
+ // } as TaskQueryReturnObject;
832
+ // }
833
+ // return {
834
+ // dismissible: false,
835
+ // severity: "primary",
836
+ // title: `Set up onboarding for ${withoutOnboarding} placements to prepare yourself and your students.`,
837
+ // message: `Click to view your placements and add or dismiss onboarding reminders.`,
838
+ // link: `/${user.product}/placementListings/placements`,
839
+ // buttonTitle: "View placements",
840
+ // } as TaskQueryReturnObject;
841
+ // },
842
+ // },
843
+ // completeListing: {
844
+ // callback: async (user) => {
845
+ // const constraints = [where("providerId", "==", user.oId), where("status", "==", "draft")];
846
+ // if (user.userGroup !== "admin") {
847
+ // if (!user.viewPlacementListings || user.viewPlacementListings === "none") return;
848
+ // if (!user.viewAddresses || user.viewAddresses === "none") return;
849
+ // if (user.viewPlacementListings === "request") {
850
+ // if (!user.visibleListings || user.visibleListings?.length === 0) return;
851
+ // constraints.push(where(documentId(), 'in', user.visibleListings));
852
+ // } else {
853
+ // // viewPlacementListings must be 'all'
854
+ // if (user.viewAddresses === "request") {
855
+ // if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
856
+ // constraints.push(where("addressId", 'in', user.visibleAddresses));
857
+ // }
858
+ // }
859
+ // }
860
+ // const incompleteListings = await firebaseQuery.getCount("placementListings", constraints);
861
+ // if (incompleteListings === 0) return;
862
+ // if (incompleteListings === 1) {
863
+ // const incompleteListing = Object.entries(await firebaseQuery.getDocsWhere("placementListings", constraints) || {})[0] as [string, PlacementListing];
864
+ // const address = incompleteListing[1].addressId ? await firebaseQuery.getDocData(["addresses", incompleteListing[1].addressId]) as OrganisationAddress : undefined;
865
+ // return {
866
+ // dismissible: false,
867
+ // severity: "info",
868
+ // 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.`,
869
+ // message: `Click to complete and publish the placement listing.`,
870
+ // link: `/${user.product}/addListing/${incompleteListing[0]}`,
871
+ // buttonTitle: "View listing",
872
+ // } as TaskQueryReturnObject;
873
+ // }
874
+ // return {
875
+ // dismissible: false,
876
+ // severity: "info",
877
+ // title: `You have ${incompleteListings} draft listings waiting to be published.`,
878
+ // message: `Click to review and publish the placement listings.`,
879
+ // link: `/${user.product}/placementListings/listings`,
880
+ // buttonTitle: "View listings",
881
+ // } as TaskQueryReturnObject;
882
+ // },
883
+ // },
884
+ // completeAddress: {
885
+ // callback: async (user) => {
886
+ // const constraints = [where("product", "==", "providers"), where("oId", "==", user.oId), where("stage", "!=", "complete")];
887
+ // if (user.userGroup !== "admin") {
888
+ // if (!user.viewAddresses || user.viewAddresses === "none") return;
889
+ // if (user.viewAddresses === "request") {
890
+ // if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
891
+ // constraints.push(where("addressId", 'in', user.visibleAddresses));
892
+ // }
893
+ // }
894
+ // const incompleteAddresses = await firebaseQuery.getCount("addresses", constraints);
895
+ // if (incompleteAddresses === 0) return;
896
+ // if (incompleteAddresses === 1) {
897
+ // const address = Object.entries(await firebaseQuery.getDocsWhere("addresses", constraints) || {})[0] as [string, OrganisationAddress];
898
+ // return {
899
+ // dismissible: false,
900
+ // severity: "info",
901
+ // title: `Your address: ${address[1]["address-line1"]}, ${address[1].postal_code.toUpperCase()}, ${capitaliseWords(camelCaseToNormal(address[1].country))} is currently incomplete.`,
902
+ // message: `Click to complete the addresses.`,
903
+ // link: `/${user.product}/addAddress/${address[0]}`,
904
+ // buttonTitle: "View address",
905
+ // } as TaskQueryReturnObject;
906
+ // }
907
+ // return {
908
+ // dismissible: false,
909
+ // severity: "info",
910
+ // title: `You have ${incompleteAddresses} draft addresses waiting to be published.`,
911
+ // message: `Click to review the addresses.`,
912
+ // link: `/${user.product}/organisation/addresses`,
913
+ // buttonTitle: "View addresses",
914
+ // } as TaskQueryReturnObject;
915
+ // },
916
+ // },
917
+ // registrationRequests: {
918
+ // callback: async (user) => {
919
+ // if (!getAccess(user, "addStaff")) return;
920
+ // const regRequests = await firebaseQuery.getCount("requests", [where("product", "==", user.product), where("oId", "==", user.oId)]);
921
+ // if (regRequests === 0) return;
922
+ // if (regRequests === 1) {
923
+ // const request = Object.entries(await firebaseQuery.getDocsWhere("requests", [where("product", "==", user.product), where("oId", "==", user.oId)]) || {})[0] as [string, RegistrationRequest];
924
+ // return {
925
+ // dismissible: false,
926
+ // severity: "primary",
927
+ // title: `${request[1].forename} ${request[1].surname} has requested to access your organisation.`,
928
+ // message: `Click to review these request.`,
929
+ // link: `/${user.product}/organisation/staff/requests`,
930
+ // buttonTitle: "View requests",
931
+ // } as TaskQueryReturnObject;
932
+ // }
933
+ // return {
934
+ // dismissible: false,
935
+ // severity: "primary",
936
+ // title: `${regRequests} people have requested to register with your organisation.`,
937
+ // message: `Click to review these requests.`,
938
+ // link: `/${user.product}/organisation/staff/requests`,
939
+ // buttonTitle: "View requests",
940
+ // } as TaskQueryReturnObject;
941
+ // },
942
+ // },
943
+ // activateStaff: {
944
+ // callback: async (user) => {
945
+ // if (!getAccess(user, "addStaff")) return;
946
+ // const inactiveAccounts = await firebaseQuery.getCount("users", [where("product", "==", user.product), where("oId", "==", user.oId), where("status", "==", "inactive")]);
947
+ // if (inactiveAccounts === 0) return;
948
+ // if (inactiveAccounts === 1) {
949
+ // const account = Object.entries(await firebaseQuery.getDocsWhere("users", [where("product", "==", user.product), where("oId", "==", user.oId), where("status", "==", "inactive")]) || {})[0] as [string, UserData];
950
+ // return {
951
+ // dismissible: false,
952
+ // severity: "info",
953
+ // title: `Activate ${account[1].details.forename} ${account[1].details.surname}'s staff account.`,
954
+ // message: "Activate this account to give the user access to Placementt.",
955
+ // link: `/${user.product}/organisation/staff/all`,
956
+ // buttonTitle: "View accounts",
957
+ // } as TaskQueryReturnObject;
958
+ // }
959
+ // return {
960
+ // dismissible: false,
961
+ // severity: "info",
962
+ // title: `${inactiveAccounts} staff have inactive active accounts.`,
963
+ // message: "Activate these accounts to give the user access to Placementt.",
964
+ // link: `/${user.product}/organisation/staff/all`,
965
+ // buttonTitle: "View accounts",
966
+ // } as TaskQueryReturnObject;
967
+ // },
968
+ // },
969
+ // placementStarting: {
970
+ // callback: async (user) => {
971
+ // const sevenDaysInFuture = new Date();
972
+ // sevenDaysInFuture.setDate(sevenDaysInFuture.getDate() + 7)
973
+ // const constraints = [where("providerId", "==", user.oId), where("startDate", "<=", convertDate(sevenDaysInFuture, "dbstring")), where("startDate", ">", dateToString(new Date()))];
974
+ // if (user.userGroup !== "admin") {
975
+ // if (!user.viewPlacementListings || user.viewPlacementListings === "none") return;
976
+ // if (!user.viewAddresses || user.viewAddresses === "none") return;
977
+ // if (user.viewPlacementListings === "request") {
978
+ // if (!user.visibleListings || user.visibleListings?.length === 0) return;
979
+ // constraints.push(where(documentId(), 'in', user.visibleListings));
980
+ // } else {
981
+ // // viewPlacementListings must be 'all'
982
+ // if (user.viewAddresses === "request") {
983
+ // if (!user.visibleAddresses || user.visibleAddresses?.length === 0) return;
984
+ // constraints.push(where("addressId", 'in', user.visibleAddresses));
985
+ // }
986
+ // }
987
+ // }
988
+ // const placementsStartingSoon = await firebaseQuery.getCount("placements", constraints);
989
+ // if (placementsStartingSoon === 0) return;
990
+ // if (placementsStartingSoon === 1) {
991
+ // const placement = Object.entries(await firebaseQuery.getDocsWhere("placements", constraints) || {})[0] as [string, StudentPlacementData];
992
+ // const student = placement[1].uid ? await firebaseQuery.getDocData(["users", placement[1].uid]) as UserData : {
993
+ // details: {
994
+ // forename: placement[1].studentForename,
995
+ // surname: placement[1].studentSurname,
996
+ // }
997
+ // };
998
+ // return {
999
+ // dismissible: false,
1000
+ // severity: "success",
1001
+ // 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.`,
1002
+ // message: `Click to view the placement and acquaint yourself with the student.`,
1003
+ // link: `/${user.product}/placements/${placement[0]}`,
1004
+ // buttonTitle: "View",
1005
+ // } as TaskQueryReturnObject;
1006
+ // }
1007
+ // return {
1008
+ // dismissible: false,
1009
+ // severity: "success",
1010
+ // title: `${placementsStartingSoon} placements starting soon.`,
1011
+ // message: `Click to view scheduled placements.`,
1012
+ // link: `/${user.product}/placementListings/placements`,
1013
+ // buttonTitle: "View placements",
1014
+ // } as TaskQueryReturnObject;
1015
+ // },
1016
+ // },
1017
+ // completeFeedback: {
1018
+ // callback: async (user) => {
1019
+ // return;
1020
+ // return {} as TaskQueryReturnObject;
1021
+ // },
1022
+ // },
1023
+ // setUpFeedback: {
1024
+ // callback: async (user) => {
1025
+ // return;
1026
+ // return {} as TaskQueryReturnObject;
1027
+ // },
1028
+ // },
1029
+ // }
1078
1030
  const getTips = async (user, organisation, addresses) => {
1079
1031
  const tipsObject = {
1080
1032
  providers: providerTips,
@@ -1107,7 +1059,7 @@ const getTasks = async ({ user, organisation, cohort, school }) => {
1107
1059
  return await getStudentTasks(user, organisation, cohort);
1108
1060
  }
1109
1061
  if (user.product === "providers" && organisation) {
1110
- return await getProviderTasks(user, organisation);
1062
+ // return await getProviderTasks(user, organisation);
1111
1063
  }
1112
1064
  return [];
1113
1065
  };
@@ -1124,18 +1076,16 @@ const getStudentTasks = async (user, organisation, cohort) => {
1124
1076
  }, Promise.resolve([]));
1125
1077
  return processedTasks;
1126
1078
  };
1127
- const getProviderTasks = async (user, organisation, cohort) => {
1128
- const processedTasks = await Object.entries(providerTasks).reduce(async (acc, [itemName, item]) => {
1129
- const queryResult = await item.callback(user);
1130
- if (!queryResult)
1131
- return await acc;
1132
- const queryResultArray = Array.isArray(queryResult) ? queryResult : [queryResult];
1133
- const results = queryResultArray.map((r) => ({ itemName: itemName, ...r }));
1134
- (await acc).push(...results);
1135
- return await acc;
1136
- }, Promise.resolve([]));
1137
- return processedTasks;
1138
- };
1079
+ // const getProviderTasks = async (user: UserData, organisation: InstituteData|ProviderData, cohort?: CohortData):Promise<(TaskQueryReturnObject)[]> => {
1080
+ // const processedTasks = await Object.entries(providerTasks).reduce(async (acc, [itemName, item]) => {
1081
+ // const queryResult = await item.callback(user);
1082
+ // if (!queryResult) return await acc;
1083
+ // const queryResultArray = Array.isArray(queryResult) ? queryResult : [queryResult];
1084
+ // const results = queryResultArray.map((r) => ({itemName: itemName as ProviderTaskNames, ...r}));
1085
+ // (await acc).push(...results);
1086
+ // return await acc;
1087
+ // }, Promise.resolve<TaskQueryReturnObject[]>([]));
1088
+ // return processedTasks;};
1139
1089
  const getInstituteTasks = async ({ user, organisation, cohort, school }) => {
1140
1090
  let fCohort = cohort;
1141
1091
  let fSchool = school;