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.
Files changed (69) hide show
  1. package/lib/constants.d.ts +1 -0
  2. package/lib/constants.js +6 -0
  3. package/lib/constants.js.map +1 -1
  4. package/lib/features/analytics/useAnalytics.d.ts +2 -0
  5. package/lib/features/analytics/useAnalytics.js +21 -16
  6. package/lib/features/analytics/useAnalytics.js.map +1 -1
  7. package/lib/features/global/downtime/useDowntime.d.ts +1 -0
  8. package/lib/features/global/downtime/useDowntime.js +9 -7
  9. package/lib/features/global/downtime/useDowntime.js.map +1 -1
  10. package/lib/features/global/users/useUserFunctions.js +1 -1
  11. package/lib/features/global/users/useUserFunctions.js.map +1 -1
  12. package/lib/features/placements/studentPlacements/activePlacement.d.ts +5 -1
  13. package/lib/features/placements/studentPlacements/activePlacement.js +7 -3
  14. package/lib/features/placements/studentPlacements/activePlacement.js.map +1 -1
  15. package/lib/features/placements/studentPlacements/completedStudentPlacementsSlice.d.ts +3 -2
  16. package/lib/features/placements/studentPlacements/completedStudentPlacementsSlice.js +4 -1
  17. package/lib/features/placements/studentPlacements/completedStudentPlacementsSlice.js.map +1 -1
  18. package/lib/features/placements/studentPlacements/upcomingStudentPlacementsSlice.d.ts +2 -2
  19. package/lib/features/placements/studentPlacements/upcomingStudentPlacementsSlice.js +1 -1
  20. package/lib/features/placements/studentPlacements/upcomingStudentPlacementsSlice.js.map +1 -1
  21. package/lib/features/placements/studentPlacements/useStudentPlacements.d.ts +2 -12
  22. package/lib/features/placements/studentPlacements/useStudentPlacements.js +1 -26
  23. package/lib/features/placements/studentPlacements/useStudentPlacements.js.map +1 -1
  24. package/lib/features/updates/useUpdates.d.ts +1 -0
  25. package/lib/features/updates/useUpdates.js +13 -12
  26. package/lib/features/updates/useUpdates.js.map +1 -1
  27. package/lib/firebase/firebase.d.ts +3 -1
  28. package/lib/firebase/firebase.js +4 -3
  29. package/lib/firebase/firebase.js.map +1 -1
  30. package/lib/firebase/firebaseQuery.d.ts +3 -1
  31. package/lib/firebase/firebaseQuery.js +8 -1
  32. package/lib/firebase/firebaseQuery.js.map +1 -1
  33. package/lib/firebase/readDatabase.d.ts +2 -4
  34. package/lib/firebase/readDatabase.js +28 -5
  35. package/lib/firebase/readDatabase.js.map +1 -1
  36. package/lib/firebase/writeDatabase.d.ts +6 -2
  37. package/lib/firebase/writeDatabase.js +2 -1
  38. package/lib/firebase/writeDatabase.js.map +1 -1
  39. package/lib/hooks.d.ts +108 -9
  40. package/lib/hooks.js +547 -58
  41. package/lib/hooks.js.map +1 -1
  42. package/lib/reduxHooks.d.ts +41 -3
  43. package/lib/reduxHooks.js +61 -18
  44. package/lib/reduxHooks.js.map +1 -1
  45. package/lib/tasksAndTips.d.ts +1 -1
  46. package/lib/tasksAndTips.js +179 -8
  47. package/lib/tasksAndTips.js.map +1 -1
  48. package/lib/typeDefinitions.d.ts +14 -22
  49. package/lib/util.js +14 -8
  50. package/lib/util.js.map +1 -1
  51. package/package.json +1 -1
  52. package/src/constants.ts +7 -1
  53. package/src/features/analytics/useAnalytics.tsx +24 -15
  54. package/src/features/global/downtime/useDowntime.tsx +11 -7
  55. package/src/features/global/users/useUserFunctions.tsx +1 -1
  56. package/src/features/placements/studentPlacements/activePlacement.ts +8 -3
  57. package/src/features/placements/studentPlacements/completedStudentPlacementsSlice.ts +5 -2
  58. package/src/features/placements/studentPlacements/upcomingStudentPlacementsSlice.ts +2 -2
  59. package/src/features/placements/studentPlacements/useStudentPlacements.tsx +4 -28
  60. package/src/features/updates/useUpdates.tsx +14 -12
  61. package/src/firebase/firebase.tsx +5 -3
  62. package/src/firebase/firebaseQuery.tsx +8 -1
  63. package/src/firebase/readDatabase.tsx +33 -6
  64. package/src/firebase/writeDatabase.tsx +3 -1
  65. package/src/hooks.tsx +695 -61
  66. package/src/reduxHooks.ts +68 -20
  67. package/src/tasksAndTips.ts +184 -11
  68. package/src/typeDefinitions.ts +14 -20
  69. 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, `userFiles/${file.fileName}`));
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
- const listingData = listing || await firebaseQuery.getDocData(["placementListings", listingId]);
1161
- const address = (user.product === "providers" && orgContext) ? orgContext.addresses[listingData.addressId || ""] : await firebaseQuery.getDocData(["addresses", listingData.addressId]);
1162
- const workflow = (user.product === "providers" && orgContext) ? orgContext.applicantWorkflows[listingData.applicantWorkflowId || ""] : await firebaseQuery.getDocData(["applicantWorkflows", listingData.applicantWorkflowId]);
1163
- workflow.workflow = await Promise.all(workflow.workflow.map(async (s) => {
1164
- var _a, _b;
1165
- const applicantFiles = s.files ? Object.fromEntries(await Promise.all((_a = s.files) === null || _a === void 0 ? void 0 : _a.map(async (fileId) => {
1166
- const file = await firebaseQuery.getDocData(["files", fileId]);
1167
- file.url = await (0, storage_1.getDownloadURL)((0, storage_1.ref)(firebaseConfig_1.storage, `userFiles/${file.fileName}`));
1168
- return [fileId, file];
1169
- }))) : [];
1170
- const applicantForms = s.forms ? Object.fromEntries(await Promise.all((_b = s.forms) === null || _b === void 0 ? void 0 : _b.map(async (formId) => {
1171
- return [formId, await firebaseQuery.getDocData(["forms", formId])];
1172
- }))) : [];
1173
- return { ...s, viewableFiles: applicantFiles, formDetails: applicantForms };
1174
- }));
1175
- delete address.id;
1176
- delete workflow.id;
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, `userFiles/${file.fileName}`));
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
- console.log(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);
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
- throw new Error("Providers cannot create applications");
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
- console.log("formData", formData);
1505
- if (formData.id && formData.uid && formData.id && draft === formData.draft) {
1506
- return await firebaseQuery.update(["placements", formData.id], formData);
1507
- }
1508
- console.log("STUDENTID", student.id);
1509
- return await (0, writeDatabase_1.addPlacement)(formData, student.id, draft).catch((e) => {
1510
- console.log("error");
1511
- console.log(e);
1512
- throw e;
1513
- }).then((e) => {
1514
- setComplete(true);
1515
- return e;
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 === "providers") && user.userGroup === "admin") {
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, _b, _c;
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
- ((_b = a === null || a === void 0 ? void 0 : a.viewableFiles) === null || _b === void 0 ? void 0 : _b[file].url) && onOpen((_c = a === null || a === void 0 ? void 0 : a.viewableFiles) === null || _c === void 0 ? void 0 : _c[file].url);
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, `userFiles/${file.fileName}`));
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
- onboardingNew.viewableFiles = onboardingFiles;
2607
- onboardingNew.formDetails = onboardingForms;
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