placementt-core 11.0.533 → 11.10.151
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/lib/constants.d.ts +1 -0
- package/lib/constants.js +6 -0
- package/lib/constants.js.map +1 -1
- package/lib/features/analytics/useAnalytics.d.ts +2 -0
- package/lib/features/analytics/useAnalytics.js +21 -16
- package/lib/features/analytics/useAnalytics.js.map +1 -1
- package/lib/features/global/downtime/useDowntime.d.ts +1 -0
- package/lib/features/global/downtime/useDowntime.js +9 -7
- package/lib/features/global/downtime/useDowntime.js.map +1 -1
- package/lib/features/global/users/useUserFunctions.js +1 -1
- package/lib/features/global/users/useUserFunctions.js.map +1 -1
- package/lib/features/placements/studentPlacements/activePlacement.d.ts +5 -1
- package/lib/features/placements/studentPlacements/activePlacement.js +7 -3
- package/lib/features/placements/studentPlacements/activePlacement.js.map +1 -1
- package/lib/features/placements/studentPlacements/completedStudentPlacementsSlice.d.ts +3 -2
- package/lib/features/placements/studentPlacements/completedStudentPlacementsSlice.js +4 -1
- package/lib/features/placements/studentPlacements/completedStudentPlacementsSlice.js.map +1 -1
- package/lib/features/placements/studentPlacements/upcomingStudentPlacementsSlice.d.ts +2 -2
- package/lib/features/placements/studentPlacements/upcomingStudentPlacementsSlice.js +1 -1
- package/lib/features/placements/studentPlacements/upcomingStudentPlacementsSlice.js.map +1 -1
- package/lib/features/placements/studentPlacements/useStudentPlacements.d.ts +2 -12
- package/lib/features/placements/studentPlacements/useStudentPlacements.js +1 -26
- package/lib/features/placements/studentPlacements/useStudentPlacements.js.map +1 -1
- package/lib/features/updates/useUpdates.d.ts +1 -0
- package/lib/features/updates/useUpdates.js +13 -12
- package/lib/features/updates/useUpdates.js.map +1 -1
- package/lib/firebase/firebase.d.ts +3 -1
- package/lib/firebase/firebase.js +4 -3
- package/lib/firebase/firebase.js.map +1 -1
- package/lib/firebase/firebaseQuery.d.ts +3 -1
- package/lib/firebase/firebaseQuery.js +8 -1
- package/lib/firebase/firebaseQuery.js.map +1 -1
- package/lib/firebase/readDatabase.d.ts +2 -4
- package/lib/firebase/readDatabase.js +28 -5
- package/lib/firebase/readDatabase.js.map +1 -1
- package/lib/firebase/writeDatabase.d.ts +6 -2
- package/lib/firebase/writeDatabase.js +2 -1
- package/lib/firebase/writeDatabase.js.map +1 -1
- package/lib/hooks.d.ts +108 -9
- package/lib/hooks.js +547 -58
- package/lib/hooks.js.map +1 -1
- package/lib/reduxHooks.d.ts +41 -3
- package/lib/reduxHooks.js +61 -18
- package/lib/reduxHooks.js.map +1 -1
- package/lib/tasksAndTips.d.ts +1 -1
- package/lib/tasksAndTips.js +179 -8
- package/lib/tasksAndTips.js.map +1 -1
- package/lib/typeDefinitions.d.ts +14 -22
- package/lib/util.js +14 -8
- package/lib/util.js.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +7 -1
- package/src/features/analytics/useAnalytics.tsx +24 -15
- package/src/features/global/downtime/useDowntime.tsx +11 -7
- package/src/features/global/users/useUserFunctions.tsx +1 -1
- package/src/features/placements/studentPlacements/activePlacement.ts +8 -3
- package/src/features/placements/studentPlacements/completedStudentPlacementsSlice.ts +5 -2
- package/src/features/placements/studentPlacements/upcomingStudentPlacementsSlice.ts +2 -2
- package/src/features/placements/studentPlacements/useStudentPlacements.tsx +4 -28
- package/src/features/updates/useUpdates.tsx +14 -12
- package/src/firebase/firebase.tsx +5 -3
- package/src/firebase/firebaseQuery.tsx +8 -1
- package/src/firebase/readDatabase.tsx +33 -6
- package/src/firebase/writeDatabase.tsx +3 -1
- package/src/hooks.tsx +695 -61
- package/src/reduxHooks.ts +68 -20
- package/src/tasksAndTips.ts +184 -11
- package/src/typeDefinitions.ts +14 -20
- package/src/util.ts +14 -9
package/lib/hooks.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.useRefDimensions = void 0;
|
|
6
|
+
exports.useFirestoreQuery = exports.useRefDimensions = void 0;
|
|
7
7
|
exports.useStudentPlacementList = useStudentPlacementList;
|
|
8
8
|
exports.useNewInstitutePlacementList = useNewInstitutePlacementList;
|
|
9
9
|
exports.useOldInstitutePlacementList = useOldInstitutePlacementList;
|
|
@@ -22,6 +22,9 @@ exports.useApplicantWorkflowEditor = useApplicantWorkflowEditor;
|
|
|
22
22
|
exports.useInstitutePlacementListingHandler = useInstitutePlacementListingHandler;
|
|
23
23
|
exports.useGetIndividualPlacementForPlacementPage = useGetIndividualPlacementForPlacementPage;
|
|
24
24
|
exports.useOnboardingPopup = useOnboardingPopup;
|
|
25
|
+
exports.useLoadAddresses = useLoadAddresses;
|
|
26
|
+
exports.useLoadListings = useLoadListings;
|
|
27
|
+
exports.useLoadApplications = useLoadApplications;
|
|
25
28
|
const firestore_1 = require("firebase/firestore");
|
|
26
29
|
const react_1 = require("react");
|
|
27
30
|
const constants_1 = require("./constants");
|
|
@@ -1109,7 +1112,7 @@ function usePublicPlacementListingLoader({ providerId, number = 5 }) {
|
|
|
1109
1112
|
const applicantWorkflow = (await firebaseQuery.getDocData(["applicantWorkflows", itemObj.applicantWorkflowId])).workflow.filter((i) => i.id === 1)[0];
|
|
1110
1113
|
const applicantFiles = applicantWorkflow.files ? Object.fromEntries(await Promise.all((_a = applicantWorkflow.files) === null || _a === void 0 ? void 0 : _a.map(async (fileId) => {
|
|
1111
1114
|
const file = await firebaseQuery.getDocData(["files", fileId]);
|
|
1112
|
-
file.url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `
|
|
1115
|
+
file.url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `providers/${itemObj.providerId}/${file.fileName}`));
|
|
1113
1116
|
return [fileId, file];
|
|
1114
1117
|
}))) : [];
|
|
1115
1118
|
const applicantForms = applicantWorkflow.forms ? Object.fromEntries(await Promise.all((_b = applicantWorkflow.forms) === null || _b === void 0 ? void 0 : _b.map(async (formId) => {
|
|
@@ -1138,6 +1141,7 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1138
1141
|
const [fApplication, setFApplication] = (0, react_1.useState)(application ? applicationWithoutAdditionalData : {
|
|
1139
1142
|
uid: user.userType === "Students" ? user.id : undefined,
|
|
1140
1143
|
listingId: listingId,
|
|
1144
|
+
addressId: listing === null || listing === void 0 ? void 0 : listing.addressId,
|
|
1141
1145
|
stage: 1,
|
|
1142
1146
|
reqUserType: "Students",
|
|
1143
1147
|
status: "draft"
|
|
@@ -1145,7 +1149,7 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1145
1149
|
const [fApplicationId, setFApplicationId] = (0, react_1.useState)(applicationId);
|
|
1146
1150
|
const [draftSaved, setDraftSaved] = (0, react_1.useState)(false);
|
|
1147
1151
|
const [fProvider, setFProvider] = (0, react_1.useState)(provider);
|
|
1148
|
-
const [fListing, setFListing] = (0, react_1.useState)(listing);
|
|
1152
|
+
const [fListing, setFListing] = (0, react_1.useState)(Object.keys(listing || {}).length > 5 ? listing : undefined);
|
|
1149
1153
|
const [student, setStudent] = (0, react_1.useState)(user.userType === "Students" ? user : undefined);
|
|
1150
1154
|
const [profileUrl, setProfileUrl] = (0, react_1.useState)();
|
|
1151
1155
|
const [successPopup, setSuccessPopup] = (0, react_1.useState)();
|
|
@@ -1157,30 +1161,35 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1157
1161
|
if (!listingId)
|
|
1158
1162
|
return;
|
|
1159
1163
|
console.log("Getting listing");
|
|
1160
|
-
|
|
1161
|
-
const
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1164
|
+
console.log("LISTING PARAM", listing, Object.keys(listing || {}).length > 5);
|
|
1165
|
+
const listingData = (Object.keys(listing || {}).length > 5) ? listing : await firebaseQuery.getDocData(["placementListings", listingId]).catch(() => false);
|
|
1166
|
+
console.log("LISTINGDATA", listingData, Object.keys(listing || {}).length > 5 ? { a: "string" } : "AAA");
|
|
1167
|
+
const address = listingData ? (user.product === "providers" && orgContext) ? orgContext.addresses[listingData.addressId || ""] : await firebaseQuery.getDocData(["addresses", listingData.addressId]) : undefined;
|
|
1168
|
+
const workflow = listingData ? (user.product === "providers" && orgContext) ? orgContext.applicantWorkflows[listingData.applicantWorkflowId || ""] : await firebaseQuery.getDocData(["applicantWorkflows", listingData.applicantWorkflowId]) : undefined;
|
|
1169
|
+
if (workflow && listingData) {
|
|
1170
|
+
workflow.workflow = await Promise.all(workflow.workflow.map(async (s) => {
|
|
1171
|
+
var _a, _b;
|
|
1172
|
+
const applicantFiles = s.files ? Object.fromEntries(await Promise.all((_a = s.files) === null || _a === void 0 ? void 0 : _a.map(async (fileId) => {
|
|
1173
|
+
const file = await firebaseQuery.getDocData(["files", fileId]);
|
|
1174
|
+
file.url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `providers/${listingData === null || listingData === void 0 ? void 0 : listingData.providerId}/${file.fileName}`));
|
|
1175
|
+
return [fileId, file];
|
|
1176
|
+
}))) : [];
|
|
1177
|
+
const applicantForms = s.forms ? Object.fromEntries(await Promise.all((_b = s.forms) === null || _b === void 0 ? void 0 : _b.map(async (formId) => {
|
|
1178
|
+
return [formId, await firebaseQuery.getDocData(["forms", formId])];
|
|
1179
|
+
}))) : [];
|
|
1180
|
+
return { ...s, viewableFiles: applicantFiles, formDetails: applicantForms };
|
|
1181
|
+
}));
|
|
1182
|
+
delete workflow.id;
|
|
1183
|
+
}
|
|
1184
|
+
if (address) {
|
|
1185
|
+
delete address.id;
|
|
1186
|
+
}
|
|
1177
1187
|
console.log("Setting listing");
|
|
1178
|
-
setFListing({ ...listingData, ...address, applicantWorkflow: workflow.workflow });
|
|
1179
|
-
console.log("Getting provider", listingData === null || listingData === void 0 ? void 0 : listingData.providerId);
|
|
1188
|
+
setFListing((listingData && workflow) ? { ...listingData, ...address, applicantWorkflow: workflow.workflow } : false);
|
|
1180
1189
|
if (((fProvider === null || fProvider === void 0 ? void 0 : fProvider.id) === (application === null || application === void 0 ? void 0 : application.providerId)) && user.product === "providers") {
|
|
1181
1190
|
setFProvider({ details: orgContext === null || orgContext === void 0 ? void 0 : orgContext.details, id: user.oId });
|
|
1182
1191
|
}
|
|
1183
|
-
else if (listingData === null || listingData === void 0 ? void 0 : listingData.providerId) {
|
|
1192
|
+
else if (listingData && (listingData === null || listingData === void 0 ? void 0 : listingData.providerId)) {
|
|
1184
1193
|
console.log("Getting provider from DB");
|
|
1185
1194
|
const provider = await firebaseQuery.getDocData(["providers", listingData.providerId]);
|
|
1186
1195
|
console.log("Provider", provider);
|
|
@@ -1200,7 +1209,7 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1200
1209
|
}
|
|
1201
1210
|
}, []);
|
|
1202
1211
|
(0, react_1.useEffect)(() => {
|
|
1203
|
-
setFListing(listing);
|
|
1212
|
+
setFListing(Object.keys(listing || {}).length > 5 ? listing : undefined);
|
|
1204
1213
|
}, [listing]);
|
|
1205
1214
|
(0, react_1.useEffect)(() => {
|
|
1206
1215
|
if (provider === null || provider === void 0 ? void 0 : provider.profile)
|
|
@@ -1224,11 +1233,25 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1224
1233
|
});
|
|
1225
1234
|
return;
|
|
1226
1235
|
}
|
|
1227
|
-
if (applicationId)
|
|
1236
|
+
if (applicationId) {
|
|
1228
1237
|
setFApplicationId(applicationId);
|
|
1238
|
+
if (application) {
|
|
1239
|
+
let applicationWithoutAdditionalData = { ...(application || {}) };
|
|
1240
|
+
delete applicationWithoutAdditionalData.listing;
|
|
1241
|
+
delete applicationWithoutAdditionalData.address;
|
|
1242
|
+
delete applicationWithoutAdditionalData.provider;
|
|
1243
|
+
setFApplication(applicationWithoutAdditionalData);
|
|
1244
|
+
}
|
|
1245
|
+
else {
|
|
1246
|
+
firebaseQuery.getDocData(["applications", applicationId]).then(setFApplication);
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1229
1249
|
}, [application, applicationId]);
|
|
1230
1250
|
const getCurrentStage = async (stage) => {
|
|
1231
1251
|
var _a, _b, _c, _d;
|
|
1252
|
+
console.log("fLSITING CURRENT STAGE", fListing);
|
|
1253
|
+
if (!fListing)
|
|
1254
|
+
throw new Error("Listing deleted");
|
|
1232
1255
|
if (!(fListing === null || fListing === void 0 ? void 0 : fListing.applicantWorkflowId))
|
|
1233
1256
|
throw new Error("No workflow stage");
|
|
1234
1257
|
const mApplicantWorkflow = await firebaseQuery.getDocData(["applicantWorkflows", fListing.applicantWorkflowId]);
|
|
@@ -1237,7 +1260,7 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1237
1260
|
throw new Error("Can't find stage.");
|
|
1238
1261
|
const applicantFiles = stageObj.files ? Object.fromEntries(await Promise.all((_b = stageObj.files) === null || _b === void 0 ? void 0 : _b.map(async (fileId) => {
|
|
1239
1262
|
const file = await firebaseQuery.getDocData(["files", fileId]);
|
|
1240
|
-
file.url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `
|
|
1263
|
+
file.url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `providers/${mApplicantWorkflow === null || mApplicantWorkflow === void 0 ? void 0 : mApplicantWorkflow.oId}/${file.fileName}`));
|
|
1241
1264
|
return [fileId, file];
|
|
1242
1265
|
}))) : [];
|
|
1243
1266
|
const applicantForms = stageObj.forms ? Object.fromEntries(await Promise.all((_c = stageObj.forms) === null || _c === void 0 ? void 0 : _c.map(async (formId) => {
|
|
@@ -1267,11 +1290,12 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1267
1290
|
};
|
|
1268
1291
|
const addApplication = async () => {
|
|
1269
1292
|
console.log("ADDING APPLICATION");
|
|
1270
|
-
if (!(fListing === null || fListing === void 0 ? void 0 : fListing.id) || !(fProvider === null || fProvider === void 0 ? void 0 : fProvider.id) || !(student === null || student === void 0 ? void 0 : student.id))
|
|
1293
|
+
if (!fListing || !(fListing === null || fListing === void 0 ? void 0 : fListing.id) || !(fProvider === null || fProvider === void 0 ? void 0 : fProvider.id) || !(student === null || student === void 0 ? void 0 : student.id))
|
|
1271
1294
|
return;
|
|
1272
1295
|
const applicationData = {
|
|
1273
1296
|
uid: student.id,
|
|
1274
1297
|
listingId: fListing === null || fListing === void 0 ? void 0 : fListing.id,
|
|
1298
|
+
addressId: fListing.addressId,
|
|
1275
1299
|
applicantWorkflowId: fListing === null || fListing === void 0 ? void 0 : fListing.applicantWorkflowId,
|
|
1276
1300
|
providerId: fProvider.id,
|
|
1277
1301
|
stage: 1,
|
|
@@ -1288,11 +1312,10 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1288
1312
|
};
|
|
1289
1313
|
getUploadedFiles();
|
|
1290
1314
|
console.log("Checking IDs");
|
|
1291
|
-
|
|
1292
|
-
if (!(fListing === null || fListing === void 0 ? void 0 : fListing.id) || !(fProvider === null || fProvider === void 0 ? void 0 : fProvider.id) || !(student === null || student === void 0 ? void 0 : student.id))
|
|
1315
|
+
if (!fListing || !(fListing === null || fListing === void 0 ? void 0 : fListing.id) || !(fProvider === null || fProvider === void 0 ? void 0 : fProvider.id) || !(student === null || student === void 0 ? void 0 : student.id))
|
|
1293
1316
|
return;
|
|
1294
1317
|
if (user.product === "providers")
|
|
1295
|
-
|
|
1318
|
+
return;
|
|
1296
1319
|
console.log("Checking dates and sections");
|
|
1297
1320
|
if (!fApplication.completedSections && !fApplication.startDate && !fApplication.endDate)
|
|
1298
1321
|
return;
|
|
@@ -1361,6 +1384,8 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1361
1384
|
return;
|
|
1362
1385
|
if (fApplication.stage === undefined)
|
|
1363
1386
|
throw new Error("Missing applciation stage.");
|
|
1387
|
+
if (!fListing)
|
|
1388
|
+
throw new Error("No associated listing.");
|
|
1364
1389
|
const viewableFiles = (_b = (_a = fListing === null || fListing === void 0 ? void 0 : fListing.applicantWorkflow) === null || _a === void 0 ? void 0 : _a.find((stage) => stage.id === fApplication.stage)) === null || _b === void 0 ? void 0 : _b.viewableFiles;
|
|
1365
1390
|
setFApplication((a) => {
|
|
1366
1391
|
var _a, _b;
|
|
@@ -1413,14 +1438,20 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1413
1438
|
openSuccessPopup("draftSaved");
|
|
1414
1439
|
return;
|
|
1415
1440
|
}
|
|
1441
|
+
if (!fApplicationId)
|
|
1442
|
+
return;
|
|
1416
1443
|
// Check all items have been filled in.
|
|
1417
1444
|
if (!fApplication.startDate || !fApplication.endDate)
|
|
1418
1445
|
throw new Error("Please select dates for your placement.");
|
|
1419
1446
|
await (0, firebase_1.executeCallable)("applications-submit", { applicationId: fApplicationId });
|
|
1447
|
+
const newApplication = await firebaseQuery.getDocData(["applications", fApplicationId]);
|
|
1448
|
+
setFApplication(newApplication);
|
|
1420
1449
|
openSuccessPopup("submitted");
|
|
1421
1450
|
};
|
|
1422
1451
|
const progressStage = async (type, e) => {
|
|
1423
1452
|
// Check all stages completed.
|
|
1453
|
+
if (!fApplicationId)
|
|
1454
|
+
return;
|
|
1424
1455
|
if (!currentStageComplete)
|
|
1425
1456
|
throw new Error("Complete all forms before submitting.");
|
|
1426
1457
|
if (fApplication.reqUserType !== user.userType)
|
|
@@ -1428,6 +1459,8 @@ function useCreateApplicationRenderer({ user, listingId, listing, provider, appl
|
|
|
1428
1459
|
if (fApplication.stage === undefined)
|
|
1429
1460
|
throw new Error("Missing applciation stage.");
|
|
1430
1461
|
await (0, firebase_1.executeCallable)("applications-changeStage", { applicationId: fApplicationId, type: type, feedback: e === null || e === void 0 ? void 0 : e.feedback });
|
|
1462
|
+
const newApplication = await firebaseQuery.getDocData(["applications", fApplicationId]);
|
|
1463
|
+
setFApplication(newApplication);
|
|
1431
1464
|
};
|
|
1432
1465
|
return { successText, onFApply, progressStage, currentStageComplete, uploadedFiles, getCurrentStage, setFormComplete, viewFile, addFile, setSuccessPopup, openSuccessPopup, setFApplication, fApplication, draftSaved, profileUrl, successPopup, fApplicationId, fListing, student, fProvider };
|
|
1433
1466
|
}
|
|
@@ -1498,22 +1531,43 @@ function useProposePlacementRenderer({ user, orgContext, placement }) {
|
|
|
1498
1531
|
setFormData(undefined);
|
|
1499
1532
|
};
|
|
1500
1533
|
const proposePlacement = async (draft = false) => {
|
|
1534
|
+
const getPlacementStatus = (startDate, endDate) => {
|
|
1535
|
+
const today = new Date();
|
|
1536
|
+
if (startDate <= today && endDate >= today)
|
|
1537
|
+
return { active: !draft ? true : false, inProgress: true, completed: false };
|
|
1538
|
+
else if (endDate <= today)
|
|
1539
|
+
return { completed: true, inProgress: false, active: false };
|
|
1540
|
+
return { completed: false, inProgress: true, active: false };
|
|
1541
|
+
};
|
|
1501
1542
|
if (!formData || !student) {
|
|
1502
1543
|
throw new Error("Cannot find placement details.");
|
|
1503
1544
|
}
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
}
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1545
|
+
try {
|
|
1546
|
+
console.log("formData", formData);
|
|
1547
|
+
const status = getPlacementStatus(new Date(formData.startDate), new Date(formData.endDate));
|
|
1548
|
+
const newFormData = { ...formData, ...status };
|
|
1549
|
+
if (newFormData.id && newFormData.uid && draft === newFormData.draft)
|
|
1550
|
+
await firebaseQuery.update(["placements", newFormData.id], newFormData);
|
|
1551
|
+
else
|
|
1552
|
+
await (0, writeDatabase_1.addPlacement)(newFormData, student.id, draft);
|
|
1553
|
+
return { status };
|
|
1554
|
+
}
|
|
1555
|
+
catch (error) {
|
|
1556
|
+
console.log("Error:", error);
|
|
1557
|
+
throw error;
|
|
1558
|
+
}
|
|
1559
|
+
/*
|
|
1560
|
+
console.log("STUDENTID", student.id);
|
|
1561
|
+
|
|
1562
|
+
return await addPlacement(formData, student.id, draft).catch((e) => {
|
|
1563
|
+
console.log("error");
|
|
1564
|
+
console.log(e);
|
|
1565
|
+
throw e;
|
|
1566
|
+
}).then((e) => {
|
|
1567
|
+
setComplete(true);
|
|
1568
|
+
return e;
|
|
1569
|
+
});
|
|
1570
|
+
*/
|
|
1517
1571
|
};
|
|
1518
1572
|
const deletePlacement = async (id) => {
|
|
1519
1573
|
return await firebaseQuery.delete(["placements", id]);
|
|
@@ -2353,6 +2407,8 @@ function useGetIndividualPlacementForPlacementPage({ user, placementId, organisa
|
|
|
2353
2407
|
const [uploadRA, setUploadRA] = (0, react_1.useState)(false);
|
|
2354
2408
|
const [uploadDBS, setUploadDBS] = (0, react_1.useState)(false);
|
|
2355
2409
|
const [onboardingPopup, setOnboardingPopup] = (0, react_1.useState)(false);
|
|
2410
|
+
const [dismissOnboardingPopup, setDismissOnboardingPopup] = (0, react_1.useState)(false);
|
|
2411
|
+
const [addOnboardingDocsPopup, setAddOnboardingDocsPopup] = (0, react_1.useState)(false);
|
|
2356
2412
|
const [editable, setEditable] = (0, react_1.useState)(false);
|
|
2357
2413
|
const [withdrawFromPlacementPopup, setWithdrawFromPlacementPopup] = (0, react_1.useState)(false);
|
|
2358
2414
|
const firebaseQuery = new firebaseQuery_1.default();
|
|
@@ -2395,7 +2451,7 @@ function useGetIndividualPlacementForPlacementPage({ user, placementId, organisa
|
|
|
2395
2451
|
setStudent(user);
|
|
2396
2452
|
}
|
|
2397
2453
|
else {
|
|
2398
|
-
(0, readDatabase_1.getUserById)(placement.uid).then(setStudent);
|
|
2454
|
+
(0, readDatabase_1.getUserById)(placement.uid, undefined, false).then(setStudent);
|
|
2399
2455
|
}
|
|
2400
2456
|
}, [placement]);
|
|
2401
2457
|
(0, react_1.useEffect)(() => {
|
|
@@ -2451,10 +2507,7 @@ function useGetIndividualPlacementForPlacementPage({ user, placementId, organisa
|
|
|
2451
2507
|
const onboardingStatus = (placement === null || placement === void 0 ? void 0 : placement.onboarding) ? ((_a = placement.onboarding.completed) === null || _a === void 0 ? void 0 : _a.submitted) ? placement.onboarding.completed.accepted ? "Onboarding docs approved" : "Onboarding docs completed" : (user.userType === "Staff" ? "Onboarding sent" : "Complete onboarding") : "Add onboarding documents";
|
|
2452
2508
|
const signOffPlacements = (0, util_1.getAccess)(user, "signOffPlacements");
|
|
2453
2509
|
let canEdit = false;
|
|
2454
|
-
if (((wStage === null || wStage === void 0 ? void 0 : wStage.userType) === "Staff" && user.product === "
|
|
2455
|
-
canEdit = true;
|
|
2456
|
-
}
|
|
2457
|
-
else if (((wStage === null || wStage === void 0 ? void 0 : wStage.userType) === "Staff" && user.userType === "Staff" && user.product === "institutes") || (user.product === "providers" && (wStage === null || wStage === void 0 ? void 0 : wStage.userType) === "Provider") || user.userType === "Students" && (wStage === null || wStage === void 0 ? void 0 : wStage.userType) === "Students") {
|
|
2510
|
+
if (((wStage === null || wStage === void 0 ? void 0 : wStage.userType) === "Staff" && user.userType === "Staff" && user.product === "institutes") || (user.product === "providers" && (wStage === null || wStage === void 0 ? void 0 : wStage.userType) === "Provider") || user.userType === "Students" && (wStage === null || wStage === void 0 ? void 0 : wStage.userType) === "Students") {
|
|
2458
2511
|
console.log("ALMOST CAN EDIT");
|
|
2459
2512
|
if (user.userType === "Staff" && !signOffPlacements) {
|
|
2460
2513
|
canEdit = false;
|
|
@@ -2463,7 +2516,7 @@ function useGetIndividualPlacementForPlacementPage({ user, placementId, organisa
|
|
|
2463
2516
|
canEdit = true;
|
|
2464
2517
|
}
|
|
2465
2518
|
}
|
|
2466
|
-
const onFlagClick = async (e) => {
|
|
2519
|
+
const onFlagClick = async (e, onClose) => {
|
|
2467
2520
|
if (!placement)
|
|
2468
2521
|
return;
|
|
2469
2522
|
if (e === "completeOnboarding" || e === "reviewOnboarding") {
|
|
@@ -2494,6 +2547,14 @@ function useGetIndividualPlacementForPlacementPage({ user, placementId, organisa
|
|
|
2494
2547
|
}
|
|
2495
2548
|
setExternalDocPopupOpen("dbsCheck");
|
|
2496
2549
|
}
|
|
2550
|
+
if (e === "addOnboarding") {
|
|
2551
|
+
if (onClose) {
|
|
2552
|
+
setDismissOnboardingPopup(true);
|
|
2553
|
+
}
|
|
2554
|
+
else {
|
|
2555
|
+
setAddOnboardingDocsPopup(true);
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2497
2558
|
};
|
|
2498
2559
|
const approveELI = async () => {
|
|
2499
2560
|
if (!placement)
|
|
@@ -2553,15 +2614,17 @@ function useGetIndividualPlacementForPlacementPage({ user, placementId, organisa
|
|
|
2553
2614
|
throw new Error("Must be a student to withdraw.");
|
|
2554
2615
|
await (0, firebase_1.executeCallable)("placement-withdraw", { placementId: placementId });
|
|
2555
2616
|
};
|
|
2556
|
-
return { placement, wStage, student, workflow, editable, withdrawFromPlacementPopup, setWithdrawFromPlacementPopup, withdrawFromPlacement, onFlagClick, setUploadInsurance, setUploadProviderDocPopup, setUploadRA, setUploadDBS, onboardingStatus, setSkipStagePopup, onboardingPopup, setViewExternalLinkPopup, setOnboardingPopup, setRejectELIPopup, eliURL, riskAssessmentURL, dbsCheckURL, setExternalLinkCopied, skipStagePopup, snackbar, setSnackbar, cohort, disableEmail, rejectELIPopup, eliPopupOpen, rejectExternalDocPopup, externalDocPopupOpen, viewExternalLinkPopup, externalLinkCopied, uploadInsurance, uploadRA, uploadDBS, editStage, sendEmail, canEdit, approveELI, setEliPopupOpen, uploadProviderDocPopup, rejectELI, setRejectExternalDocPopup, setExternalDocPopupOpen, approveProviderDoc, rejectProviderDoc, manuallyConfigureProvider, institute };
|
|
2617
|
+
return { placement, wStage, student, workflow, editable, withdrawFromPlacementPopup, addOnboardingDocsPopup, setAddOnboardingDocsPopup, dismissOnboardingPopup, setDismissOnboardingPopup, setWithdrawFromPlacementPopup, withdrawFromPlacement, onFlagClick, setUploadInsurance, setUploadProviderDocPopup, setUploadRA, setUploadDBS, onboardingStatus, setSkipStagePopup, onboardingPopup, setViewExternalLinkPopup, setOnboardingPopup, setRejectELIPopup, eliURL, riskAssessmentURL, dbsCheckURL, setExternalLinkCopied, skipStagePopup, snackbar, setSnackbar, cohort, disableEmail, rejectELIPopup, eliPopupOpen, rejectExternalDocPopup, externalDocPopupOpen, viewExternalLinkPopup, externalLinkCopied, uploadInsurance, uploadRA, uploadDBS, editStage, sendEmail, canEdit, approveELI, setEliPopupOpen, uploadProviderDocPopup, rejectELI, setRejectExternalDocPopup, setExternalDocPopupOpen, approveProviderDoc, rejectProviderDoc, manuallyConfigureProvider, institute };
|
|
2557
2618
|
}
|
|
2558
|
-
function useOnboardingPopup({ onboarding, placementId, user, onClose }) {
|
|
2619
|
+
function useOnboardingPopup({ onboarding, providerId, placementId, user, onClose }) {
|
|
2559
2620
|
const [fileUploadPopup, setFileUploadPopup] = (0, react_1.useState)(false);
|
|
2560
2621
|
const [form, setForm] = (0, react_1.useState)();
|
|
2561
2622
|
const [rejectPopup, setRejectPopup] = (0, react_1.useState)(false);
|
|
2562
2623
|
const [mOnboarding, setMOnboarding] = (0, react_1.useState)(onboarding);
|
|
2563
2624
|
const [completedSections, setCompletedSections] = (0, react_1.useState)();
|
|
2564
2625
|
const [uploadedFiles, setUploadedFiles] = (0, react_1.useState)({});
|
|
2626
|
+
const [viewableFiles, setViewableFiles] = (0, react_1.useState)();
|
|
2627
|
+
const [formDetails, setFormDetails] = (0, react_1.useState)({});
|
|
2565
2628
|
const firebaseQuery = new firebaseQuery_1.default();
|
|
2566
2629
|
const addFile = (files) => {
|
|
2567
2630
|
if (!files.length || fileUploadPopup === false)
|
|
@@ -2571,12 +2634,12 @@ function useOnboardingPopup({ onboarding, placementId, user, onClose }) {
|
|
|
2571
2634
|
};
|
|
2572
2635
|
const viewFile = (file, onOpen) => {
|
|
2573
2636
|
setMOnboarding((a) => {
|
|
2574
|
-
var _a
|
|
2637
|
+
var _a;
|
|
2575
2638
|
const oldA = { ...a };
|
|
2576
2639
|
const viewedFiles = a.completed ? ((_a = a.completed) === null || _a === void 0 ? void 0 : _a.filesViewed) || [] : [];
|
|
2577
2640
|
if (viewedFiles === null || viewedFiles === void 0 ? void 0 : viewedFiles.includes(file))
|
|
2578
2641
|
return a;
|
|
2579
|
-
(
|
|
2642
|
+
(viewableFiles === null || viewableFiles === void 0 ? void 0 : viewableFiles[file].url) && onOpen(viewableFiles === null || viewableFiles === void 0 ? void 0 : viewableFiles[file].url);
|
|
2580
2643
|
viewedFiles === null || viewedFiles === void 0 ? void 0 : viewedFiles.push(file);
|
|
2581
2644
|
const newA = (0, util_1.editNestedObject)(["completed", "filesViewed"], oldA, viewedFiles);
|
|
2582
2645
|
return newA;
|
|
@@ -2597,14 +2660,14 @@ function useOnboardingPopup({ onboarding, placementId, user, onClose }) {
|
|
|
2597
2660
|
const onboardingNew = { ...onboarding };
|
|
2598
2661
|
const onboardingFiles = onboarding.files ? Object.fromEntries(await Promise.all((_a = onboarding.files) === null || _a === void 0 ? void 0 : _a.map(async (fileId) => {
|
|
2599
2662
|
const file = await firebaseQuery.getDocData(["files", fileId]);
|
|
2600
|
-
file.url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `
|
|
2663
|
+
file.url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `providers/${providerId}/${file.fileName}`));
|
|
2601
2664
|
return [fileId, file];
|
|
2602
2665
|
}))) : [];
|
|
2603
2666
|
const onboardingForms = onboarding.forms ? Object.fromEntries(await Promise.all((_b = onboarding.forms) === null || _b === void 0 ? void 0 : _b.map(async (formId) => {
|
|
2604
2667
|
return [formId, await firebaseQuery.getDocData(["forms", formId])];
|
|
2605
2668
|
}))) : [];
|
|
2606
|
-
|
|
2607
|
-
|
|
2669
|
+
setViewableFiles(onboardingFiles);
|
|
2670
|
+
setFormDetails(onboardingForms);
|
|
2608
2671
|
return onboardingNew;
|
|
2609
2672
|
};
|
|
2610
2673
|
getOnboardingData().then(setMOnboarding);
|
|
@@ -2659,7 +2722,7 @@ function useOnboardingPopup({ onboarding, placementId, user, onClose }) {
|
|
|
2659
2722
|
return;
|
|
2660
2723
|
if (!stagesCompleted())
|
|
2661
2724
|
throw new Error("Complete all forms before submitting.");
|
|
2662
|
-
await firebaseQuery.update(["placements", placementId], { ["onboarding.completed.submitted"]: (0, util_1.convertDate)(new Date(), "dbstring") });
|
|
2725
|
+
await firebaseQuery.update(["placements", placementId], { ["onboarding.completed.accepted"]: false, ["onboarding.completed.submitted"]: true, ["onboarding.completed.submittedDate"]: (0, util_1.convertDate)(new Date(), "dbstring") });
|
|
2663
2726
|
};
|
|
2664
2727
|
(0, react_1.useEffect)(() => {
|
|
2665
2728
|
const getUploadedFiles = async () => {
|
|
@@ -2695,6 +2758,432 @@ function useOnboardingPopup({ onboarding, placementId, user, onClose }) {
|
|
|
2695
2758
|
getUploadedFiles();
|
|
2696
2759
|
addCompletedSectionURLs();
|
|
2697
2760
|
}, [mOnboarding]);
|
|
2698
|
-
return { addFile, viewFile, uploadedFiles, setFormComplete, setRejectPopup, stagesCompleted, setForm, mOnboarding, form, submit, acceptOnboarding, rejectOnboarding, rejectPopup, completedSections, fileUploadPopup, setFileUploadPopup };
|
|
2761
|
+
return { addFile, viewFile, uploadedFiles, setFormComplete, setRejectPopup, stagesCompleted, setForm, mOnboarding, form, submit, acceptOnboarding, rejectOnboarding, rejectPopup, completedSections, fileUploadPopup, setFileUploadPopup, viewableFiles, formDetails };
|
|
2699
2762
|
}
|
|
2763
|
+
function useLoadAddresses(user, limitItems, queryConstraint) {
|
|
2764
|
+
const [addresses, setAddresses] = (0, react_1.useState)({});
|
|
2765
|
+
const [lastDoc, setLastDoc] = (0, react_1.useState)(null);
|
|
2766
|
+
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
2767
|
+
const firebaseQuery = new firebaseQuery_1.default();
|
|
2768
|
+
const [queryConstraints, setQueryConstraints] = (0, react_1.useState)(queryConstraint || []);
|
|
2769
|
+
const changeQueryConstraints = (e) => {
|
|
2770
|
+
setQueryConstraints([...(queryConstraint || []), ...e]);
|
|
2771
|
+
};
|
|
2772
|
+
const loadAddresses = () => {
|
|
2773
|
+
var _a, _b, _c;
|
|
2774
|
+
const constraints = [(0, firestore_1.where)("oId", "==", user.oId), (0, firestore_1.where)("product", "==", user.product), (0, firestore_1.orderBy)((0, firestore_1.documentId)())];
|
|
2775
|
+
if (limitItems) {
|
|
2776
|
+
constraints.push((0, firestore_1.limit)(limitItems));
|
|
2777
|
+
}
|
|
2778
|
+
if (((_a = user.groupData) === null || _a === void 0 ? void 0 : _a.viewAddresses) === "all" || user.userGroup === "admin") {
|
|
2779
|
+
if (lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id) {
|
|
2780
|
+
constraints.push((0, firestore_1.startAfter)(lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id));
|
|
2781
|
+
}
|
|
2782
|
+
}
|
|
2783
|
+
else if (((_b = user.groupData) === null || _b === void 0 ? void 0 : _b.viewAddresses) === "request") {
|
|
2784
|
+
if (!((_c = user.visibleAddresses) === null || _c === void 0 ? void 0 : _c.length))
|
|
2785
|
+
return;
|
|
2786
|
+
constraints.push((0, firestore_1.where)((0, firestore_1.documentId)(), "in", user.visibleAddresses));
|
|
2787
|
+
if (lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id) {
|
|
2788
|
+
constraints.push((0, firestore_1.startAfter)(lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id));
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
else {
|
|
2792
|
+
setLoading(false);
|
|
2793
|
+
return; // viewAddresses === "none", no need to load anything
|
|
2794
|
+
}
|
|
2795
|
+
queryConstraints && constraints.unshift(...queryConstraints);
|
|
2796
|
+
return firebaseQuery.collectionSnapshot((async (snapshot) => {
|
|
2797
|
+
const deletedAddresses = snapshot.docChanges().map((change) => {
|
|
2798
|
+
if (change.type === "removed") {
|
|
2799
|
+
return change.doc.id;
|
|
2800
|
+
}
|
|
2801
|
+
return;
|
|
2802
|
+
});
|
|
2803
|
+
setAddresses((prev) => Object.fromEntries(Object.entries(prev).filter(([k]) => !deletedAddresses.includes(k))));
|
|
2804
|
+
if (!snapshot.empty) {
|
|
2805
|
+
const newAddresses = snapshot.docs.map(doc => ([doc.id, { id: doc.id, ...doc.data() }]));
|
|
2806
|
+
const withListings = Object.fromEntries(await Promise.all(newAddresses.map(async ([k, address]) => {
|
|
2807
|
+
const listings = await firebaseQuery.getCount("placementListings", [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.where)("addressId", "==", k)]);
|
|
2808
|
+
return [k, { ...address, listings: listings }];
|
|
2809
|
+
})));
|
|
2810
|
+
setAddresses(prev => ({ ...prev, ...withListings }));
|
|
2811
|
+
setLastDoc(snapshot.docs[snapshot.docs.length - 1]);
|
|
2812
|
+
}
|
|
2813
|
+
setLoading(false);
|
|
2814
|
+
}), "addresses", constraints, undefined, true);
|
|
2815
|
+
};
|
|
2816
|
+
(0, react_1.useEffect)(() => {
|
|
2817
|
+
const unsubscribe = loadAddresses();
|
|
2818
|
+
return () => {
|
|
2819
|
+
if (unsubscribe) {
|
|
2820
|
+
unsubscribe(); // Unsubscribe from the snapshot listener when the component unmounts
|
|
2821
|
+
}
|
|
2822
|
+
};
|
|
2823
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2824
|
+
}, [queryConstraints]);
|
|
2825
|
+
const onScrollBottom = () => {
|
|
2826
|
+
if (!limitItems)
|
|
2827
|
+
return;
|
|
2828
|
+
if (!loading) {
|
|
2829
|
+
setLoading(true);
|
|
2830
|
+
loadAddresses();
|
|
2831
|
+
}
|
|
2832
|
+
};
|
|
2833
|
+
return { addresses, onScrollBottom, loading, changeQueryConstraints };
|
|
2834
|
+
}
|
|
2835
|
+
function useLoadListings(user, queryConstraint) {
|
|
2836
|
+
const [listings, setListings] = (0, react_1.useState)([]);
|
|
2837
|
+
const [lastDoc, setLastDoc] = (0, react_1.useState)(null);
|
|
2838
|
+
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
2839
|
+
const firebaseQuery = new firebaseQuery_1.default();
|
|
2840
|
+
const [queryConstraints, setQueryConstraints] = (0, react_1.useState)(queryConstraint || []);
|
|
2841
|
+
const changeQueryConstraints = (e) => {
|
|
2842
|
+
setQueryConstraints([...(queryConstraint || []), ...e]);
|
|
2843
|
+
};
|
|
2844
|
+
const loadListings = () => {
|
|
2845
|
+
var _a, _b, _c, _d, _e;
|
|
2846
|
+
const constraints = [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.limit)(10), (0, firestore_1.orderBy)((0, firestore_1.documentId)())];
|
|
2847
|
+
if (((_a = user.groupData) === null || _a === void 0 ? void 0 : _a.viewPlacementListings) === "all" || user.userGroup === "admin") {
|
|
2848
|
+
if (lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id) {
|
|
2849
|
+
constraints.push((0, firestore_1.startAfter)(lastDoc));
|
|
2850
|
+
}
|
|
2851
|
+
}
|
|
2852
|
+
else if (((_b = user.groupData) === null || _b === void 0 ? void 0 : _b.viewPlacementListings) === "request") {
|
|
2853
|
+
if (!((_c = user.visibleListings) === null || _c === void 0 ? void 0 : _c.length))
|
|
2854
|
+
return;
|
|
2855
|
+
constraints.push((0, firestore_1.where)((0, firestore_1.documentId)(), 'in', user.visibleListings));
|
|
2856
|
+
if (lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id) {
|
|
2857
|
+
constraints.push((0, firestore_1.startAfter)(lastDoc));
|
|
2858
|
+
}
|
|
2859
|
+
}
|
|
2860
|
+
if (((_d = user.groupData) === null || _d === void 0 ? void 0 : _d.viewAddresses) !== "all" && user.userGroup !== "admin") {
|
|
2861
|
+
if (!((_e = user.visibleAddresses) === null || _e === void 0 ? void 0 : _e.length))
|
|
2862
|
+
return;
|
|
2863
|
+
constraints.push((0, firestore_1.where)('addressId', 'in', user.visibleAddresses));
|
|
2864
|
+
}
|
|
2865
|
+
queryConstraints && constraints.unshift(...queryConstraints);
|
|
2866
|
+
return firebaseQuery.collectionSnapshot((async (snapshot) => {
|
|
2867
|
+
const deletedListings = snapshot.docChanges().map((change) => {
|
|
2868
|
+
if (change.type === "removed") {
|
|
2869
|
+
return change.doc.id;
|
|
2870
|
+
}
|
|
2871
|
+
return;
|
|
2872
|
+
});
|
|
2873
|
+
setListings((prev) => prev.filter(([k]) => !deletedListings.includes(k)));
|
|
2874
|
+
if (!snapshot.empty) {
|
|
2875
|
+
const newListings = snapshot.docs.map(doc => ([doc.id, { ...doc.data(), id: doc.id }]));
|
|
2876
|
+
const listingsWithAdditionalData = await Promise.all(newListings.map(async ([id, listing]) => {
|
|
2877
|
+
const listingWithAdditionalData = { ...listing };
|
|
2878
|
+
if (listingWithAdditionalData.applicants !== undefined)
|
|
2879
|
+
return [id, listingWithAdditionalData];
|
|
2880
|
+
listingWithAdditionalData.applicants = await firebaseQuery.getCount("applications", [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.where)("placementId", "==", id), (0, firestore_1.where)("status", "==", "submitted")]);
|
|
2881
|
+
listingWithAdditionalData.scheduled = await firebaseQuery.getCount("placements", [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.where)("placementId", "==", id), (0, firestore_1.where)("inProgress", "==", true), (0, firestore_1.where)("startDate", ">", (0, util_1.convertDate)(new Date(), "dbstring"))]);
|
|
2882
|
+
listingWithAdditionalData.active = await firebaseQuery.getCount("placements", [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.where)("placementId", "==", id), (0, firestore_1.where)("active", "==", true)]);
|
|
2883
|
+
return [id, listingWithAdditionalData];
|
|
2884
|
+
}));
|
|
2885
|
+
setListings(prev => (Object.entries({ ...Object.fromEntries(prev), ...Object.fromEntries(listingsWithAdditionalData) })));
|
|
2886
|
+
setLastDoc(snapshot.docs[snapshot.docs.length - 1]);
|
|
2887
|
+
}
|
|
2888
|
+
setLoading(false);
|
|
2889
|
+
}), "placementListings", constraints, undefined, true);
|
|
2890
|
+
};
|
|
2891
|
+
(0, react_1.useEffect)(() => {
|
|
2892
|
+
let unsubscribe;
|
|
2893
|
+
loadListings();
|
|
2894
|
+
return () => {
|
|
2895
|
+
if (unsubscribe) {
|
|
2896
|
+
unsubscribe(); // Unsubscribe from the snapshot listener when the component unmounts
|
|
2897
|
+
}
|
|
2898
|
+
};
|
|
2899
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2900
|
+
}, [queryConstraints]);
|
|
2901
|
+
const onScrollBottom = () => {
|
|
2902
|
+
if (!loading) {
|
|
2903
|
+
setLoading(true);
|
|
2904
|
+
loadListings();
|
|
2905
|
+
}
|
|
2906
|
+
};
|
|
2907
|
+
return { listings, onScrollBottom, loading, changeQueryConstraints };
|
|
2908
|
+
}
|
|
2909
|
+
function useLoadApplications({ user, applicationType, listingId, queryConstraint }) {
|
|
2910
|
+
const [applications, setApplications] = (0, react_1.useState)([]);
|
|
2911
|
+
const [lastDoc, setLastDoc] = (0, react_1.useState)(null);
|
|
2912
|
+
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
2913
|
+
const [type, setType] = (0, react_1.useState)(applicationType || "all");
|
|
2914
|
+
const firebaseQuery = new firebaseQuery_1.default();
|
|
2915
|
+
const [queryConstraints, setQueryConstraints] = (0, react_1.useState)(queryConstraint || []);
|
|
2916
|
+
const changeQueryConstraints = (e) => {
|
|
2917
|
+
setQueryConstraints([...(queryConstraint || []), ...e]);
|
|
2918
|
+
};
|
|
2919
|
+
const loadApplications = () => {
|
|
2920
|
+
var _a, _b, _c, _d;
|
|
2921
|
+
const constraints = [(0, firestore_1.where)("providerId", "==", user.oId), (0, firestore_1.limit)(10), (0, firestore_1.orderBy)((0, firestore_1.documentId)())];
|
|
2922
|
+
if (lastDoc === null || lastDoc === void 0 ? void 0 : lastDoc.id) {
|
|
2923
|
+
constraints.push((0, firestore_1.startAfter)(lastDoc));
|
|
2924
|
+
}
|
|
2925
|
+
switch (type) {
|
|
2926
|
+
case "actionRequired":
|
|
2927
|
+
constraints.push((0, firestore_1.where)("status", "==", "submitted"), (0, firestore_1.where)("reqUserType", "==", "Staff"));
|
|
2928
|
+
break;
|
|
2929
|
+
case "awaitingStudent":
|
|
2930
|
+
constraints.push((0, firestore_1.where)("status", "==", "submitted"), (0, firestore_1.where)("reqUserType", "==", "Students"));
|
|
2931
|
+
break;
|
|
2932
|
+
case "closed":
|
|
2933
|
+
constraints.push((0, firestore_1.where)("status", "in", ["approved", "declined"]));
|
|
2934
|
+
break;
|
|
2935
|
+
default:
|
|
2936
|
+
constraints.push((0, firestore_1.where)("status", "==", "submitted"));
|
|
2937
|
+
}
|
|
2938
|
+
if (listingId) {
|
|
2939
|
+
constraints.push((0, firestore_1.where)("listingId", "==", listingId));
|
|
2940
|
+
}
|
|
2941
|
+
console.log("Constraints before user group check", constraints);
|
|
2942
|
+
if (((_a = user.groupData) === null || _a === void 0 ? void 0 : _a.viewAddresses) !== "all" && user.userGroup !== "admin") {
|
|
2943
|
+
if (((_b = user.groupData) === null || _b === void 0 ? void 0 : _b.viewPlacementListings) === "all") {
|
|
2944
|
+
if (!((_c = user.visibleAddresses) === null || _c === void 0 ? void 0 : _c.length))
|
|
2945
|
+
return;
|
|
2946
|
+
constraints.push((0, firestore_1.where)('addressId', 'in', user.visibleAddresses));
|
|
2947
|
+
}
|
|
2948
|
+
else {
|
|
2949
|
+
if (!((_d = user.visibleListings) === null || _d === void 0 ? void 0 : _d.length))
|
|
2950
|
+
return;
|
|
2951
|
+
constraints.push((0, firestore_1.where)('placementId', 'in', user.visibleListings));
|
|
2952
|
+
}
|
|
2953
|
+
}
|
|
2954
|
+
queryConstraints && constraints.unshift(...queryConstraints);
|
|
2955
|
+
console.log("Constraints after user group check", constraints);
|
|
2956
|
+
return firebaseQuery.collectionSnapshot((async (snapshot) => {
|
|
2957
|
+
const deletedApplications = snapshot.docChanges().map((change) => {
|
|
2958
|
+
if (change.type === "removed") {
|
|
2959
|
+
return change.doc.id;
|
|
2960
|
+
}
|
|
2961
|
+
return;
|
|
2962
|
+
});
|
|
2963
|
+
console.log("applicantCount", snapshot.size);
|
|
2964
|
+
setApplications((prev) => prev.filter(([k]) => !deletedApplications.includes(k)));
|
|
2965
|
+
if (!snapshot.empty) {
|
|
2966
|
+
const newApplications = snapshot.docs.map(doc => ([doc.id, { id: doc.id, ...doc.data() }])).filter(([, v]) => v.status !== "draft");
|
|
2967
|
+
setApplications(prev => ([...prev, ...newApplications]));
|
|
2968
|
+
setLastDoc(snapshot.docs[snapshot.docs.length - 1]);
|
|
2969
|
+
}
|
|
2970
|
+
setLoading(false);
|
|
2971
|
+
}), "applications", constraints, undefined, true);
|
|
2972
|
+
};
|
|
2973
|
+
(0, react_1.useEffect)(() => {
|
|
2974
|
+
let unsubscribe;
|
|
2975
|
+
loadApplications();
|
|
2976
|
+
return () => {
|
|
2977
|
+
if (unsubscribe) {
|
|
2978
|
+
unsubscribe(); // Unsubscribe from the snapshot listener when the component unmounts
|
|
2979
|
+
}
|
|
2980
|
+
};
|
|
2981
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2982
|
+
}, [type, queryConstraints]);
|
|
2983
|
+
const onScrollBottom = () => {
|
|
2984
|
+
if (!loading) {
|
|
2985
|
+
setLoading(true);
|
|
2986
|
+
loadApplications();
|
|
2987
|
+
}
|
|
2988
|
+
};
|
|
2989
|
+
return { applications, type, setType, onScrollBottom, loading, changeQueryConstraints };
|
|
2990
|
+
}
|
|
2991
|
+
const useFirestoreQuery = (firebaseQuery, props) => {
|
|
2992
|
+
const { path, constraints = [], view, limit: itemsPerPage, formatItems, snapshot = false, filters = {}, search, onSearch, data: predefinedData } = props;
|
|
2993
|
+
const [data, setData] = (0, react_1.useState)(predefinedData || {});
|
|
2994
|
+
const [loading, setLoading] = (0, react_1.useState)(true);
|
|
2995
|
+
const [lastVisible, setLastVisible] = (0, react_1.useState)(null);
|
|
2996
|
+
const [firstVisible, setFirstVisible] = (0, react_1.useState)(null);
|
|
2997
|
+
const [currentPage, setCurrentPage] = (0, react_1.useState)(0);
|
|
2998
|
+
const listenersRef = (0, react_1.useRef)({});
|
|
2999
|
+
const buildConstraints = (0, react_1.useCallback)(() => {
|
|
3000
|
+
const allConstraints = [...constraints];
|
|
3001
|
+
Object.entries(filters).forEach(([key, value]) => {
|
|
3002
|
+
allConstraints.push((0, firestore_1.where)(key, '==', value));
|
|
3003
|
+
});
|
|
3004
|
+
return allConstraints;
|
|
3005
|
+
}, [constraints, filters]);
|
|
3006
|
+
const paginateData = (0, react_1.useCallback)((items, page) => {
|
|
3007
|
+
const startIndex = page * itemsPerPage;
|
|
3008
|
+
const endIndex = startIndex + itemsPerPage;
|
|
3009
|
+
const paginatedData = Object.entries(items).slice(startIndex, endIndex).reduce((acc, [key, value]) => {
|
|
3010
|
+
acc[key] = value;
|
|
3011
|
+
return acc;
|
|
3012
|
+
}, {});
|
|
3013
|
+
return paginatedData;
|
|
3014
|
+
}, [itemsPerPage]);
|
|
3015
|
+
const filterData = (0, react_1.useCallback)((items, searchString) => {
|
|
3016
|
+
const filteredData = Object.entries(items).filter(([key, value]) => {
|
|
3017
|
+
const itemString = JSON.stringify(value).toLowerCase();
|
|
3018
|
+
return itemString.includes(searchString.toLowerCase());
|
|
3019
|
+
}).reduce((acc, [key, value]) => {
|
|
3020
|
+
acc[key] = value;
|
|
3021
|
+
return acc;
|
|
3022
|
+
}, {});
|
|
3023
|
+
return filteredData;
|
|
3024
|
+
}, []);
|
|
3025
|
+
const applyFormatItems = (0, react_1.useCallback)(async (key, item) => {
|
|
3026
|
+
if (formatItems) {
|
|
3027
|
+
const result = formatItems(key, item);
|
|
3028
|
+
return result instanceof Promise ? await result : result;
|
|
3029
|
+
}
|
|
3030
|
+
return { key, item };
|
|
3031
|
+
}, [formatItems]);
|
|
3032
|
+
const setSearch = (0, react_1.useCallback)(async (newSearch, page = 0) => {
|
|
3033
|
+
if (predefinedData) {
|
|
3034
|
+
let results = predefinedData;
|
|
3035
|
+
if (newSearch) {
|
|
3036
|
+
results = filterData(results, newSearch);
|
|
3037
|
+
}
|
|
3038
|
+
const paginatedResults = paginateData(results, page);
|
|
3039
|
+
setData(paginatedResults);
|
|
3040
|
+
setLoading(Object.keys(paginatedResults).length < itemsPerPage ? 'loaded' : false);
|
|
3041
|
+
return;
|
|
3042
|
+
}
|
|
3043
|
+
if (onSearch) {
|
|
3044
|
+
setLoading(true);
|
|
3045
|
+
const results = await onSearch(newSearch, page, itemsPerPage);
|
|
3046
|
+
setData(results);
|
|
3047
|
+
setLoading(results && Object.keys(results).length < itemsPerPage ? 'loaded' : false);
|
|
3048
|
+
}
|
|
3049
|
+
}, [onSearch, itemsPerPage, filterData, paginateData, predefinedData]);
|
|
3050
|
+
const fetchData = (0, react_1.useCallback)(async (direction) => {
|
|
3051
|
+
if (snapshot) {
|
|
3052
|
+
return;
|
|
3053
|
+
}
|
|
3054
|
+
if (predefinedData) {
|
|
3055
|
+
setLoading(false);
|
|
3056
|
+
let results = predefinedData;
|
|
3057
|
+
if (search) {
|
|
3058
|
+
results = filterData(results, search);
|
|
3059
|
+
}
|
|
3060
|
+
const paginatedResults = paginateData(results, currentPage);
|
|
3061
|
+
setData(paginatedResults);
|
|
3062
|
+
setLoading(Object.keys(paginatedResults).length < itemsPerPage ? 'loaded' : false);
|
|
3063
|
+
return;
|
|
3064
|
+
}
|
|
3065
|
+
setLoading(true);
|
|
3066
|
+
const constraintsWithLimit = [...buildConstraints(), (0, firestore_1.limit)(itemsPerPage)];
|
|
3067
|
+
if (view === 'list' && lastVisible && direction === 'up') {
|
|
3068
|
+
constraintsWithLimit.push((0, firestore_1.startAfter)(lastVisible));
|
|
3069
|
+
}
|
|
3070
|
+
if (view === 'table' && direction) {
|
|
3071
|
+
if (direction === 'up' && lastVisible) {
|
|
3072
|
+
constraintsWithLimit.push((0, firestore_1.startAfter)(lastVisible));
|
|
3073
|
+
}
|
|
3074
|
+
if (direction === 'down' && firstVisible) {
|
|
3075
|
+
constraintsWithLimit.push((0, firestore_1.endBefore)(firstVisible));
|
|
3076
|
+
}
|
|
3077
|
+
}
|
|
3078
|
+
const results = await firebaseQuery.getDocsWhere(path, constraintsWithLimit, true);
|
|
3079
|
+
if (Object.keys(results).length === 0) {
|
|
3080
|
+
setLoading('loaded');
|
|
3081
|
+
return;
|
|
3082
|
+
}
|
|
3083
|
+
const formattedResults = {};
|
|
3084
|
+
for (const [key, item] of Object.entries(results)) {
|
|
3085
|
+
const formatted = await applyFormatItems(key, item);
|
|
3086
|
+
formattedResults[formatted.key] = formatted.item;
|
|
3087
|
+
}
|
|
3088
|
+
setData(prevData => (direction === 'down' ? formattedResults : { ...prevData, ...formattedResults }));
|
|
3089
|
+
const docEntries = Object.entries(results);
|
|
3090
|
+
if (direction === 'up' || !direction) {
|
|
3091
|
+
setLastVisible(docEntries[docEntries.length - 1][1]);
|
|
3092
|
+
}
|
|
3093
|
+
if (direction === 'down' || !direction) {
|
|
3094
|
+
setFirstVisible(docEntries[0][1]);
|
|
3095
|
+
}
|
|
3096
|
+
setLoading(false);
|
|
3097
|
+
}, [buildConstraints, firebaseQuery, applyFormatItems, lastVisible, firstVisible, view, snapshot, predefinedData, filterData, paginateData, currentPage, itemsPerPage]);
|
|
3098
|
+
const pageUp = (0, react_1.useCallback)(() => {
|
|
3099
|
+
setCurrentPage(prevPage => {
|
|
3100
|
+
const newPage = prevPage + 1;
|
|
3101
|
+
if (search && onSearch) {
|
|
3102
|
+
setSearch(search, newPage);
|
|
3103
|
+
}
|
|
3104
|
+
else {
|
|
3105
|
+
fetchData('up');
|
|
3106
|
+
}
|
|
3107
|
+
return newPage;
|
|
3108
|
+
});
|
|
3109
|
+
}, [fetchData, onSearch, search, setSearch]);
|
|
3110
|
+
const pageDown = (0, react_1.useCallback)(() => {
|
|
3111
|
+
setCurrentPage(prevPage => {
|
|
3112
|
+
const newPage = Math.max(prevPage - 1, 0);
|
|
3113
|
+
if (search && onSearch) {
|
|
3114
|
+
setSearch(search, newPage);
|
|
3115
|
+
}
|
|
3116
|
+
else {
|
|
3117
|
+
fetchData('down');
|
|
3118
|
+
}
|
|
3119
|
+
return newPage;
|
|
3120
|
+
});
|
|
3121
|
+
}, [fetchData, onSearch, search, setSearch]);
|
|
3122
|
+
const reset = (0, react_1.useCallback)(() => {
|
|
3123
|
+
setData(predefinedData || {});
|
|
3124
|
+
setLastVisible(null);
|
|
3125
|
+
setFirstVisible(null);
|
|
3126
|
+
setCurrentPage(0);
|
|
3127
|
+
setLoading(true);
|
|
3128
|
+
fetchData();
|
|
3129
|
+
}, [fetchData, predefinedData]);
|
|
3130
|
+
const setQueries = (0, react_1.useCallback)((newConstraints) => {
|
|
3131
|
+
reset();
|
|
3132
|
+
}, [reset]);
|
|
3133
|
+
const setFilters = (0, react_1.useCallback)((newFilters) => {
|
|
3134
|
+
reset();
|
|
3135
|
+
}, [reset]);
|
|
3136
|
+
(0, react_1.useEffect)(() => {
|
|
3137
|
+
if (!search) {
|
|
3138
|
+
fetchData();
|
|
3139
|
+
}
|
|
3140
|
+
else {
|
|
3141
|
+
setSearch(search, 0);
|
|
3142
|
+
}
|
|
3143
|
+
}, [fetchData, search, setSearch]);
|
|
3144
|
+
(0, react_1.useEffect)(() => {
|
|
3145
|
+
if (snapshot && path) {
|
|
3146
|
+
const constraintsWithLimit = [...buildConstraints(), (0, firestore_1.limit)(itemsPerPage)];
|
|
3147
|
+
const handleSnapshot = (querySnapshot) => {
|
|
3148
|
+
const items = {};
|
|
3149
|
+
querySnapshot.docs.forEach((doc) => {
|
|
3150
|
+
items[doc.id] = doc.data();
|
|
3151
|
+
});
|
|
3152
|
+
if (search) {
|
|
3153
|
+
const filteredData = filterData(items, search);
|
|
3154
|
+
const paginatedData = paginateData(filteredData, currentPage);
|
|
3155
|
+
setData(paginatedData);
|
|
3156
|
+
}
|
|
3157
|
+
else {
|
|
3158
|
+
const paginatedData = paginateData(items, currentPage);
|
|
3159
|
+
setData(paginatedData);
|
|
3160
|
+
}
|
|
3161
|
+
setLastVisible(querySnapshot.docs[querySnapshot.docs.length - 1] || null);
|
|
3162
|
+
setFirstVisible(querySnapshot.docs[0] || null);
|
|
3163
|
+
setLoading(Object.keys(items).length < itemsPerPage ? 'loaded' : false);
|
|
3164
|
+
};
|
|
3165
|
+
const unsubscribe = firebaseQuery.collectionSnapshot(handleSnapshot, path, constraintsWithLimit, undefined, true);
|
|
3166
|
+
listenersRef.current[path.toString()] = unsubscribe;
|
|
3167
|
+
return () => {
|
|
3168
|
+
if (listenersRef.current[path.toString()]) {
|
|
3169
|
+
listenersRef.current[path.toString()]();
|
|
3170
|
+
}
|
|
3171
|
+
};
|
|
3172
|
+
}
|
|
3173
|
+
return () => {
|
|
3174
|
+
Object.values(listenersRef.current).forEach(unsub => unsub());
|
|
3175
|
+
};
|
|
3176
|
+
}, [path, snapshot, buildConstraints, itemsPerPage, filterData, paginateData, currentPage, search, firebaseQuery]);
|
|
3177
|
+
return {
|
|
3178
|
+
data,
|
|
3179
|
+
loading,
|
|
3180
|
+
pageUp,
|
|
3181
|
+
pageDown: view === 'table' ? pageDown : undefined,
|
|
3182
|
+
setQueries,
|
|
3183
|
+
reset,
|
|
3184
|
+
setFilters,
|
|
3185
|
+
setSearch,
|
|
3186
|
+
};
|
|
3187
|
+
};
|
|
3188
|
+
exports.useFirestoreQuery = useFirestoreQuery;
|
|
2700
3189
|
//# sourceMappingURL=hooks.js.map
|