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.
- package/.eslintrc.js +40 -40
- package/.gitattributes +2 -2
- package/deploy-all.js +75 -0
- package/lib/config.d.ts +0 -13
- package/lib/config.js +1 -3
- package/lib/config.js.map +1 -1
- package/lib/constants.d.ts +1 -0
- package/lib/constants.js +48 -1
- package/lib/constants.js.map +1 -1
- package/lib/features/config.d.ts +133 -133
- package/lib/features/config.js +35 -35
- package/lib/features/contacts/contacts.d.ts +75 -75
- package/lib/features/contacts/contacts.js +105 -105
- package/lib/features/downtime/useDowntime.d.ts +11 -11
- package/lib/features/downtime/useDowntime.js +22 -22
- package/lib/features/placements/studentPlacements/activePlacement.js +1 -1
- package/lib/features/placements/studentPlacements/activePlacement.js.map +1 -1
- package/lib/features/placements/studentPlacements/studentPlacementsSlice.d.ts +63 -63
- package/lib/features/placements/studentPlacements/studentPlacementsSlice.js +81 -81
- package/lib/features/providerPlacements/providerPlacementsSlice.d.ts +19 -19
- package/lib/features/providerPlacements/providerPlacementsSlice.js +24 -24
- package/lib/features/studentPlacements/studentPlacementsSlice.d.ts +62 -62
- package/lib/features/studentPlacements/studentPlacementsSlice.js +87 -87
- package/lib/features/studentPlacements/useStudentPlacements.d.ts +6 -6
- package/lib/features/studentPlacements/useStudentPlacements.js +18 -18
- package/lib/features/userSlice.d.ts +26 -26
- package/lib/features/userSlice.js +23 -23
- package/lib/features/users/useUserFunctions.d.ts +25 -25
- package/lib/features/users/useUserFunctions.js +124 -124
- package/lib/features/users/userSlice.d.ts +46 -46
- package/lib/features/users/userSlice.js +48 -48
- package/lib/firebase/firebase.d.ts +1 -1
- package/lib/firebase/firebase.js +8 -3
- package/lib/firebase/firebase.js.map +1 -1
- package/lib/firebase/firebaseConfig.js +1 -0
- package/lib/firebase/firebaseConfig.js.map +1 -1
- package/lib/firebase/readDatabase.js +7 -7
- package/lib/firebase/readDatabase.js.map +1 -1
- package/lib/hooks.d.ts +85 -192
- package/lib/hooks.js +731 -671
- package/lib/hooks.js.map +1 -1
- package/lib/images/GatsbyBenchmarks.d.ts +1 -2
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/index.js.map +1 -1
- package/lib/reduxHooks.d.ts +9 -41
- package/lib/reduxHooks.js +1 -49
- package/lib/reduxHooks.js.map +1 -1
- package/lib/tasksAndTips.js +368 -418
- package/lib/tasksAndTips.js.map +1 -1
- package/lib/typeDefinitions.d.ts +162 -83
- package/lib/util.d.ts +25 -1
- package/lib/util.js +329 -2
- package/lib/util.js.map +1 -1
- package/package.json +56 -56
- package/src/DatabaseDefinitions.ts +18 -18
- package/src/apiCalls.ts +128 -128
- package/src/config.ts +50 -53
- package/src/constants.ts +846 -796
- package/src/databaseTypes.ts +42 -42
- package/src/features/analytics/useAnalytics.tsx +63 -63
- package/src/features/contacts/contactsSlice.ts +147 -147
- package/src/features/contacts/useContacts.tsx +73 -73
- package/src/features/dropdown/useDropdown.tsx +52 -52
- package/src/features/global/downtime/useDowntime.tsx +23 -23
- package/src/features/global/users/useUserFunctions.tsx +132 -132
- package/src/features/jobs/jobsSlice.ts +71 -71
- package/src/features/placements/studentPlacements/activePlacement.ts +68 -68
- package/src/features/placements/studentPlacements/completedStudentPlacementsSlice.ts +97 -97
- package/src/features/placements/studentPlacements/upcomingStudentPlacementsSlice.ts +108 -108
- package/src/features/placements/studentPlacements/useStudentPlacements.tsx +9 -9
- package/src/features/placements/types.ts +10 -10
- package/src/features/referrals/useReferrals.tsx +56 -56
- package/src/features/updates/useUpdates.tsx +38 -38
- package/src/firebase/firebase.tsx +158 -153
- package/src/firebase/firebaseConfig.tsx +47 -45
- package/src/firebase/firebaseQuery.tsx +151 -151
- package/src/firebase/persistence.ts +84 -84
- package/src/firebase/readDatabase.tsx +236 -236
- package/src/firebase/util.tsx +352 -352
- package/src/firebase/writeDatabase.tsx +77 -77
- package/src/hooks.tsx +4476 -4463
- package/src/images/GatsbyBenchmarks.tsx +711 -711
- package/src/images/LogFuturePlacement.jsx +64 -64
- package/src/images/LogPreviousPlacement.jsx +228 -228
- package/src/images/gatsby_benchmarks.svg +466 -466
- package/src/images/log_future_placement.svg +114 -114
- package/src/images/log_previous_placement.svg +199 -199
- package/src/index.ts +34 -35
- package/src/readDatabase.tsx +3 -3
- package/src/reduxHooks.ts +295 -352
- package/src/tasksAndTips.ts +1267 -1267
- package/src/tutorialTips.ts +58 -58
- package/src/typeDefinitions.ts +1260 -1129
- package/src/util.ts +523 -177
- package/tsconfig.dev.json +5 -5
- package/tsconfig.json +21 -21
- package/lib/features/logs/logsSlice.d.ts +0 -93
- package/lib/features/logs/logsSlice.js +0 -146
- package/lib/features/logs/logsSlice.js.map +0 -1
- package/src/features/logs/logsSlice.ts +0 -208
package/lib/tasksAndTips.js
CHANGED
|
@@ -670,411 +670,363 @@ const studentTasks = {
|
|
|
670
670
|
},
|
|
671
671
|
}
|
|
672
672
|
};
|
|
673
|
-
const providerTasks = {
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
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
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
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;
|