placementt-core 1.20.217 → 11.0.803
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +40 -40
- package/.gitattributes +2 -2
- package/lib/constants.js +10 -1
- package/lib/constants.js.map +1 -1
- package/lib/features/config.d.ts +133 -133
- package/lib/features/config.js +35 -35
- package/lib/features/contacts/contacts.d.ts +75 -75
- package/lib/features/contacts/contacts.js +105 -105
- package/lib/features/downtime/useDowntime.d.ts +11 -11
- package/lib/features/downtime/useDowntime.js +22 -22
- package/lib/features/placements/studentPlacements/studentPlacementsSlice.d.ts +63 -63
- package/lib/features/placements/studentPlacements/studentPlacementsSlice.js +81 -81
- package/lib/features/providerPlacements/providerPlacementsSlice.d.ts +19 -19
- package/lib/features/providerPlacements/providerPlacementsSlice.js +24 -24
- package/lib/features/studentPlacements/studentPlacementsSlice.d.ts +62 -62
- package/lib/features/studentPlacements/studentPlacementsSlice.js +87 -87
- package/lib/features/studentPlacements/useStudentPlacements.d.ts +6 -6
- package/lib/features/studentPlacements/useStudentPlacements.js +18 -18
- package/lib/features/userSlice.d.ts +26 -26
- package/lib/features/userSlice.js +23 -23
- package/lib/features/users/useUserFunctions.d.ts +25 -25
- package/lib/features/users/useUserFunctions.js +124 -124
- package/lib/features/users/userSlice.d.ts +46 -46
- package/lib/features/users/userSlice.js +48 -48
- package/lib/firebase/firebase.d.ts +1 -1
- package/lib/firebase/firebase.js +6 -2
- package/lib/firebase/firebase.js.map +1 -1
- package/lib/firebase/readDatabase.js +3 -1
- package/lib/firebase/readDatabase.js.map +1 -1
- package/lib/hooks.d.ts +33 -5
- package/lib/hooks.js +143 -107
- package/lib/hooks.js.map +1 -1
- package/lib/images/GatsbyBenchmarks.d.ts +1 -2
- package/lib/reduxHooks.d.ts +1 -66
- package/lib/reduxHooks.js +9 -69
- package/lib/reduxHooks.js.map +1 -1
- package/lib/tasksAndTips.d.ts +2 -2
- package/lib/tasksAndTips.js +37 -6
- package/lib/tasksAndTips.js.map +1 -1
- package/lib/typeDefinitions.d.ts +50 -5
- package/lib/util.d.ts +1 -1
- package/lib/util.js +12 -1
- package/lib/util.js.map +1 -1
- package/package.json +52 -56
- package/src/DatabaseDefinitions.ts +18 -18
- package/src/apiCalls.ts +128 -128
- package/src/config.ts +50 -50
- package/src/constants.ts +796 -787
- package/src/databaseTypes.ts +42 -42
- package/src/features/analytics/useAnalytics.tsx +63 -63
- package/src/features/contacts/contactsSlice.ts +147 -147
- package/src/features/contacts/useContacts.tsx +73 -73
- package/src/features/dropdown/useDropdown.tsx +52 -52
- package/src/features/global/downtime/useDowntime.tsx +23 -23
- package/src/features/global/users/useUserFunctions.tsx +132 -132
- package/src/features/jobs/jobsSlice.ts +71 -71
- package/src/features/placements/studentPlacements/activePlacement.ts +68 -68
- package/src/features/placements/studentPlacements/completedStudentPlacementsSlice.ts +97 -97
- package/src/features/placements/studentPlacements/upcomingStudentPlacementsSlice.ts +108 -108
- package/src/features/placements/studentPlacements/useStudentPlacements.tsx +9 -9
- package/src/features/placements/types.ts +10 -10
- package/src/features/referrals/useReferrals.tsx +56 -56
- package/src/features/updates/useUpdates.tsx +38 -38
- package/src/firebase/firebase.tsx +149 -145
- package/src/firebase/firebaseConfig.tsx +45 -45
- package/src/firebase/firebaseQuery.tsx +151 -151
- package/src/firebase/persistence.ts +84 -84
- package/src/firebase/readDatabase.tsx +236 -235
- package/src/firebase/util.tsx +352 -352
- package/src/firebase/writeDatabase.tsx +77 -77
- package/src/hooks.tsx +4353 -4323
- package/src/images/GatsbyBenchmarks.tsx +711 -711
- package/src/images/LogFuturePlacement.jsx +64 -64
- package/src/images/LogPreviousPlacement.jsx +228 -228
- package/src/images/gatsby_benchmarks.svg +466 -466
- package/src/images/log_future_placement.svg +114 -114
- package/src/images/log_previous_placement.svg +199 -199
- package/src/index.ts +34 -34
- package/src/readDatabase.tsx +3 -3
- package/src/reduxHooks.ts +232 -297
- package/src/tasksAndTips.ts +1209 -1177
- package/src/tutorialTips.ts +58 -58
- package/src/typeDefinitions.ts +1003 -958
- package/src/util.ts +160 -150
- package/tsconfig.dev.json +5 -5
- package/tsconfig.json +21 -22
package/src/databaseTypes.ts
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
// import {WorkflowStage} from "./typeDefinitions";
|
|
2
|
-
|
|
3
|
-
export type StudentUser = {
|
|
4
|
-
UserID: string,
|
|
5
|
-
forename: string,
|
|
6
|
-
surname: string,
|
|
7
|
-
email:string,
|
|
8
|
-
created: Date,
|
|
9
|
-
referral: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export type InstituteStudentUser = {
|
|
13
|
-
UserID: string,
|
|
14
|
-
forename: string,
|
|
15
|
-
surname: string,
|
|
16
|
-
email: string,
|
|
17
|
-
created: Date,
|
|
18
|
-
activated: Date,
|
|
19
|
-
cohortID: string,
|
|
20
|
-
// cohortData: Cohort
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export type InstituteStaffUser = {
|
|
24
|
-
UserID: string,
|
|
25
|
-
forename: string,
|
|
26
|
-
surname: string,
|
|
27
|
-
email: string,
|
|
28
|
-
created: Date,
|
|
29
|
-
activated: Date,
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export type ProviderUser = {
|
|
33
|
-
UserID: string,
|
|
34
|
-
}
|
|
35
|
-
/*
|
|
36
|
-
export type Cohort = {
|
|
37
|
-
CohortID: string,
|
|
38
|
-
name: string,
|
|
39
|
-
created: Date,
|
|
40
|
-
workflow: WorkflowStage[],
|
|
41
|
-
}
|
|
42
|
-
*/
|
|
1
|
+
// import {WorkflowStage} from "./typeDefinitions";
|
|
2
|
+
|
|
3
|
+
export type StudentUser = {
|
|
4
|
+
UserID: string,
|
|
5
|
+
forename: string,
|
|
6
|
+
surname: string,
|
|
7
|
+
email:string,
|
|
8
|
+
created: Date,
|
|
9
|
+
referral: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type InstituteStudentUser = {
|
|
13
|
+
UserID: string,
|
|
14
|
+
forename: string,
|
|
15
|
+
surname: string,
|
|
16
|
+
email: string,
|
|
17
|
+
created: Date,
|
|
18
|
+
activated: Date,
|
|
19
|
+
cohortID: string,
|
|
20
|
+
// cohortData: Cohort
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type InstituteStaffUser = {
|
|
24
|
+
UserID: string,
|
|
25
|
+
forename: string,
|
|
26
|
+
surname: string,
|
|
27
|
+
email: string,
|
|
28
|
+
created: Date,
|
|
29
|
+
activated: Date,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type ProviderUser = {
|
|
33
|
+
UserID: string,
|
|
34
|
+
}
|
|
35
|
+
/*
|
|
36
|
+
export type Cohort = {
|
|
37
|
+
CohortID: string,
|
|
38
|
+
name: string,
|
|
39
|
+
created: Date,
|
|
40
|
+
workflow: WorkflowStage[],
|
|
41
|
+
}
|
|
42
|
+
*/
|
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
import {useState} from "react"
|
|
2
|
-
import FirebaseQuery from "../../firebase/firebaseQuery"
|
|
3
|
-
import {where} from "firebase/firestore"
|
|
4
|
-
import {StudentPlacementData, UserData} from "../../typeDefinitions"
|
|
5
|
-
import {useAppDispatch} from "../../reduxHooks"
|
|
6
|
-
import {updateUpcomingStudentPlacement} from "../placements/studentPlacements/upcomingStudentPlacementsSlice"
|
|
7
|
-
import { updateCompletedStudentPlacement } from "../placements/studentPlacements/completedStudentPlacementsSlice"
|
|
8
|
-
|
|
9
|
-
export function useAnalyticsCard({user}: {user: UserData}){
|
|
10
|
-
const [total, setTotal] = useState<number>();
|
|
11
|
-
const [completed, setCompleted] = useState<number>();
|
|
12
|
-
const [_, setPlacementsWithoutAnalytics] = useState<{[key:string]: StudentPlacementData}>();
|
|
13
|
-
const firebaseQuery = new FirebaseQuery();
|
|
14
|
-
|
|
15
|
-
const fetchAnalyticsCardDetails = async () => {
|
|
16
|
-
try {
|
|
17
|
-
setTotal(await firebaseQuery.getCount("placements", [where("uid", "==", user.id)]))
|
|
18
|
-
setCompleted(await firebaseQuery.getCount("placements", [where("uid", "==", user.id), where("completed", "==", true)]))
|
|
19
|
-
setPlacementsWithoutAnalytics(await firebaseQuery.getDocsWhere("placements", [where("uid", "==", user.id)]) as {[key:string]: StudentPlacementData});
|
|
20
|
-
|
|
21
|
-
} catch(error) {
|
|
22
|
-
console.log(error)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return ({...{total, completed, fetchAnalyticsCardDetails}})
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function useAnalyticsViews(user: UserData | null){
|
|
32
|
-
const [placementsWithoutAnalytics, setPlacementsWithoutAnalytics] = useState<{[key:string]: StudentPlacementData}>();
|
|
33
|
-
const firebaseQuery = new FirebaseQuery();
|
|
34
|
-
|
|
35
|
-
const fetchAnalyticsViews = async () => {
|
|
36
|
-
try {
|
|
37
|
-
const docs = await firebaseQuery.getDocsWhere("placements", [where("uid", "==", user?.id)])
|
|
38
|
-
const p = Object.fromEntries(Object.entries(docs as {[key:string]: StudentPlacementData}).filter(([_, v]) => (!v.units || !v.personalAnalytics)))
|
|
39
|
-
setPlacementsWithoutAnalytics(p)
|
|
40
|
-
|
|
41
|
-
} catch(error) {
|
|
42
|
-
console.log(error)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
return ({...{placementsWithoutAnalytics, fetchAnalyticsViews}})
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export function useReviewPlacementItem(id: string, onComplete: () => void){
|
|
52
|
-
const [analytics, setAnalytics] = useState<{units: string|undefined, personalAnalytics: string[]|undefined}>();
|
|
53
|
-
const dispatch = useAppDispatch()
|
|
54
|
-
|
|
55
|
-
const submitPlacementData = async (type: "upcoming" | "completed") => {
|
|
56
|
-
if (!analytics?.units) return;
|
|
57
|
-
// await firebaseQuery.update(["placements", id], analytics);
|
|
58
|
-
type === "upcoming" ? dispatch(updateUpcomingStudentPlacement({placementId: id, attributes: analytics})) : dispatch(updateCompletedStudentPlacement({placementId: id, attributes: analytics}))
|
|
59
|
-
onComplete()
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return ({...{analytics, setAnalytics, submitPlacementData}})
|
|
63
|
-
|
|
1
|
+
import {useState} from "react"
|
|
2
|
+
import FirebaseQuery from "../../firebase/firebaseQuery"
|
|
3
|
+
import {where} from "firebase/firestore"
|
|
4
|
+
import {StudentPlacementData, UserData} from "../../typeDefinitions"
|
|
5
|
+
import {useAppDispatch} from "../../reduxHooks"
|
|
6
|
+
import {updateUpcomingStudentPlacement} from "../placements/studentPlacements/upcomingStudentPlacementsSlice"
|
|
7
|
+
import { updateCompletedStudentPlacement } from "../placements/studentPlacements/completedStudentPlacementsSlice"
|
|
8
|
+
|
|
9
|
+
export function useAnalyticsCard({user}: {user: UserData}){
|
|
10
|
+
const [total, setTotal] = useState<number>();
|
|
11
|
+
const [completed, setCompleted] = useState<number>();
|
|
12
|
+
const [_, setPlacementsWithoutAnalytics] = useState<{[key:string]: StudentPlacementData}>();
|
|
13
|
+
const firebaseQuery = new FirebaseQuery();
|
|
14
|
+
|
|
15
|
+
const fetchAnalyticsCardDetails = async () => {
|
|
16
|
+
try {
|
|
17
|
+
setTotal(await firebaseQuery.getCount("placements", [where("uid", "==", user.id)]))
|
|
18
|
+
setCompleted(await firebaseQuery.getCount("placements", [where("uid", "==", user.id), where("completed", "==", true)]))
|
|
19
|
+
setPlacementsWithoutAnalytics(await firebaseQuery.getDocsWhere("placements", [where("uid", "==", user.id)]) as {[key:string]: StudentPlacementData});
|
|
20
|
+
|
|
21
|
+
} catch(error) {
|
|
22
|
+
console.log(error)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
return ({...{total, completed, fetchAnalyticsCardDetails}})
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function useAnalyticsViews(user: UserData | null){
|
|
32
|
+
const [placementsWithoutAnalytics, setPlacementsWithoutAnalytics] = useState<{[key:string]: StudentPlacementData}>();
|
|
33
|
+
const firebaseQuery = new FirebaseQuery();
|
|
34
|
+
|
|
35
|
+
const fetchAnalyticsViews = async () => {
|
|
36
|
+
try {
|
|
37
|
+
const docs = await firebaseQuery.getDocsWhere("placements", [where("uid", "==", user?.id)])
|
|
38
|
+
const p = Object.fromEntries(Object.entries(docs as {[key:string]: StudentPlacementData}).filter(([_, v]) => (!v.units || !v.personalAnalytics)))
|
|
39
|
+
setPlacementsWithoutAnalytics(p)
|
|
40
|
+
|
|
41
|
+
} catch(error) {
|
|
42
|
+
console.log(error)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return ({...{placementsWithoutAnalytics, fetchAnalyticsViews}})
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function useReviewPlacementItem(id: string, onComplete: () => void){
|
|
52
|
+
const [analytics, setAnalytics] = useState<{units: string|undefined, personalAnalytics: string[]|undefined}>();
|
|
53
|
+
const dispatch = useAppDispatch()
|
|
54
|
+
|
|
55
|
+
const submitPlacementData = async (type: "upcoming" | "completed") => {
|
|
56
|
+
if (!analytics?.units) return;
|
|
57
|
+
// await firebaseQuery.update(["placements", id], analytics);
|
|
58
|
+
type === "upcoming" ? dispatch(updateUpcomingStudentPlacement({placementId: id, attributes: analytics})) : dispatch(updateCompletedStudentPlacement({placementId: id, attributes: analytics}))
|
|
59
|
+
onComplete()
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return ({...{analytics, setAnalytics, submitPlacementData}})
|
|
63
|
+
|
|
64
64
|
}
|
|
@@ -1,148 +1,148 @@
|
|
|
1
|
-
import {createSlice, createAsyncThunk} from "@reduxjs/toolkit";
|
|
2
|
-
import {Contact} from "../../typeDefinitions";
|
|
3
|
-
import FirebaseQuery from "../../firebase/firebaseQuery";
|
|
4
|
-
import {DocumentData, QueryConstraint, QueryDocumentSnapshot, QuerySnapshot} from "firebase/firestore";
|
|
5
|
-
|
|
6
|
-
type InitialContactState = {
|
|
7
|
-
status: string;
|
|
8
|
-
lastContact: QueryDocumentSnapshot<DocumentData> | undefined;
|
|
9
|
-
values: {
|
|
10
|
-
[key: string]: {
|
|
11
|
-
[key: string]: unknown;
|
|
12
|
-
};
|
|
13
|
-
};
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const initialState: InitialContactState = {
|
|
18
|
-
status: "",
|
|
19
|
-
lastContact: undefined,
|
|
20
|
-
values: {},
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export const fetchContacts = createAsyncThunk(
|
|
24
|
-
"contacts/fetchContacts",
|
|
25
|
-
async ({ formattedConstraints }: {formattedConstraints?: QueryConstraint | QueryConstraint[] }, { rejectWithValue}) => {
|
|
26
|
-
const firebaseQuery = new FirebaseQuery();
|
|
27
|
-
try {
|
|
28
|
-
const documents = await firebaseQuery.getDocsWhere("contacts", formattedConstraints, true) as QuerySnapshot<DocumentData>;
|
|
29
|
-
return documents
|
|
30
|
-
|
|
31
|
-
} catch (error) {
|
|
32
|
-
return rejectWithValue(error);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
export const addContact = createAsyncThunk(
|
|
39
|
-
"contacts/addContact",
|
|
40
|
-
async ({ contactForm, userId }: { contactForm: Contact; userId: string }, { rejectWithValue }) => {
|
|
41
|
-
const firebaseQuery = new FirebaseQuery();
|
|
42
|
-
try {
|
|
43
|
-
await firebaseQuery.add(["contacts"], {...contactForm, uid: userId})
|
|
44
|
-
return contactForm
|
|
45
|
-
|
|
46
|
-
} catch (error) {
|
|
47
|
-
return rejectWithValue(error);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
export const updateContact = createAsyncThunk(
|
|
54
|
-
"contacts/updateContact",
|
|
55
|
-
async ({contactId, attributes }: { contactId: string, attributes: any }, { rejectWithValue }) => {
|
|
56
|
-
const firebaseQuery = new FirebaseQuery();
|
|
57
|
-
try {
|
|
58
|
-
await firebaseQuery.update(["contacts", contactId], attributes);
|
|
59
|
-
return {contactId, attributes}
|
|
60
|
-
|
|
61
|
-
} catch (error) {
|
|
62
|
-
return rejectWithValue(error);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
export const deleteContact = createAsyncThunk(
|
|
68
|
-
"contacts/deleteContact",
|
|
69
|
-
async ({ contactId }: { contactId: string }, { rejectWithValue }) => {
|
|
70
|
-
const firebaseQuery = new FirebaseQuery();
|
|
71
|
-
try {
|
|
72
|
-
await firebaseQuery.delete(["contacts", contactId])
|
|
73
|
-
return contactId
|
|
74
|
-
|
|
75
|
-
} catch (error) {
|
|
76
|
-
return rejectWithValue(error);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
export const contactsSlice = createSlice({
|
|
85
|
-
name: "contacts",
|
|
86
|
-
initialState,
|
|
87
|
-
|
|
88
|
-
reducers: {
|
|
89
|
-
setContacts: (state, action) => {
|
|
90
|
-
state.values = action.payload
|
|
91
|
-
},
|
|
92
|
-
|
|
93
|
-
addContacts: (state, action) => {
|
|
94
|
-
state.values = {...state.values, ...action.payload}
|
|
95
|
-
},
|
|
96
|
-
|
|
97
|
-
setLastContact: (state, action) => {
|
|
98
|
-
state.lastContact = action.payload
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
extraReducers(builder){
|
|
104
|
-
builder
|
|
105
|
-
.addCase(fetchContacts.pending, (state) => {
|
|
106
|
-
state.status = "loading"
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
.addCase(fetchContacts.fulfilled, (state, action) => {
|
|
110
|
-
state.status = "success";
|
|
111
|
-
const newContacts = Object.fromEntries(
|
|
112
|
-
action.payload.docs.map(doc => [doc.id, { ...doc.data(), docPath: doc.ref }])
|
|
113
|
-
);
|
|
114
|
-
return {
|
|
115
|
-
...state,
|
|
116
|
-
values: {
|
|
117
|
-
...state.values,
|
|
118
|
-
...newContacts
|
|
119
|
-
},
|
|
120
|
-
lastContact: action.payload.docs[action.payload.docs.length - 1]
|
|
121
|
-
};
|
|
122
|
-
})
|
|
123
|
-
.addCase(fetchContacts.rejected, (state) => {
|
|
124
|
-
state.status = "rejected"
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
.addCase(addContact.fulfilled, (state, action) => {
|
|
128
|
-
const newContact = action.payload
|
|
129
|
-
const newContacts = {...state.values}
|
|
130
|
-
newContacts[action.payload.id] = newContact
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
.addCase(updateContact.fulfilled, (state, action) => {
|
|
134
|
-
state.values[action.payload.contactId] = { ...state.values[action.payload.contactId], ...action.payload.attributes };
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
.addCase(deleteContact.fulfilled, (state, action) => {
|
|
138
|
-
const contactIdToDelete = action.payload;
|
|
139
|
-
const newContacts = { ...state, values: { ...state.values } };
|
|
140
|
-
delete newContacts.values[contactIdToDelete];
|
|
141
|
-
return newContacts;
|
|
142
|
-
})
|
|
143
|
-
}
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
export const {setContacts, setLastContact, addContacts} = contactsSlice.actions;
|
|
147
|
-
|
|
1
|
+
import {createSlice, createAsyncThunk} from "@reduxjs/toolkit";
|
|
2
|
+
import {Contact} from "../../typeDefinitions";
|
|
3
|
+
import FirebaseQuery from "../../firebase/firebaseQuery";
|
|
4
|
+
import {DocumentData, QueryConstraint, QueryDocumentSnapshot, QuerySnapshot} from "firebase/firestore";
|
|
5
|
+
|
|
6
|
+
type InitialContactState = {
|
|
7
|
+
status: string;
|
|
8
|
+
lastContact: QueryDocumentSnapshot<DocumentData> | undefined;
|
|
9
|
+
values: {
|
|
10
|
+
[key: string]: {
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
const initialState: InitialContactState = {
|
|
18
|
+
status: "",
|
|
19
|
+
lastContact: undefined,
|
|
20
|
+
values: {},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const fetchContacts = createAsyncThunk(
|
|
24
|
+
"contacts/fetchContacts",
|
|
25
|
+
async ({ formattedConstraints }: {formattedConstraints?: QueryConstraint | QueryConstraint[] }, { rejectWithValue}) => {
|
|
26
|
+
const firebaseQuery = new FirebaseQuery();
|
|
27
|
+
try {
|
|
28
|
+
const documents = await firebaseQuery.getDocsWhere("contacts", formattedConstraints, true) as QuerySnapshot<DocumentData>;
|
|
29
|
+
return documents
|
|
30
|
+
|
|
31
|
+
} catch (error) {
|
|
32
|
+
return rejectWithValue(error);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
export const addContact = createAsyncThunk(
|
|
39
|
+
"contacts/addContact",
|
|
40
|
+
async ({ contactForm, userId }: { contactForm: Contact; userId: string }, { rejectWithValue }) => {
|
|
41
|
+
const firebaseQuery = new FirebaseQuery();
|
|
42
|
+
try {
|
|
43
|
+
await firebaseQuery.add(["contacts"], {...contactForm, uid: userId})
|
|
44
|
+
return contactForm
|
|
45
|
+
|
|
46
|
+
} catch (error) {
|
|
47
|
+
return rejectWithValue(error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
export const updateContact = createAsyncThunk(
|
|
54
|
+
"contacts/updateContact",
|
|
55
|
+
async ({contactId, attributes }: { contactId: string, attributes: any }, { rejectWithValue }) => {
|
|
56
|
+
const firebaseQuery = new FirebaseQuery();
|
|
57
|
+
try {
|
|
58
|
+
await firebaseQuery.update(["contacts", contactId], attributes);
|
|
59
|
+
return {contactId, attributes}
|
|
60
|
+
|
|
61
|
+
} catch (error) {
|
|
62
|
+
return rejectWithValue(error);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
export const deleteContact = createAsyncThunk(
|
|
68
|
+
"contacts/deleteContact",
|
|
69
|
+
async ({ contactId }: { contactId: string }, { rejectWithValue }) => {
|
|
70
|
+
const firebaseQuery = new FirebaseQuery();
|
|
71
|
+
try {
|
|
72
|
+
await firebaseQuery.delete(["contacts", contactId])
|
|
73
|
+
return contactId
|
|
74
|
+
|
|
75
|
+
} catch (error) {
|
|
76
|
+
return rejectWithValue(error);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
export const contactsSlice = createSlice({
|
|
85
|
+
name: "contacts",
|
|
86
|
+
initialState,
|
|
87
|
+
|
|
88
|
+
reducers: {
|
|
89
|
+
setContacts: (state, action) => {
|
|
90
|
+
state.values = action.payload
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
addContacts: (state, action) => {
|
|
94
|
+
state.values = {...state.values, ...action.payload}
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
setLastContact: (state, action) => {
|
|
98
|
+
state.lastContact = action.payload
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
extraReducers(builder){
|
|
104
|
+
builder
|
|
105
|
+
.addCase(fetchContacts.pending, (state) => {
|
|
106
|
+
state.status = "loading"
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
.addCase(fetchContacts.fulfilled, (state, action) => {
|
|
110
|
+
state.status = "success";
|
|
111
|
+
const newContacts = Object.fromEntries(
|
|
112
|
+
action.payload.docs.map(doc => [doc.id, { ...doc.data(), docPath: doc.ref }])
|
|
113
|
+
);
|
|
114
|
+
return {
|
|
115
|
+
...state,
|
|
116
|
+
values: {
|
|
117
|
+
...state.values,
|
|
118
|
+
...newContacts
|
|
119
|
+
},
|
|
120
|
+
lastContact: action.payload.docs[action.payload.docs.length - 1]
|
|
121
|
+
};
|
|
122
|
+
})
|
|
123
|
+
.addCase(fetchContacts.rejected, (state) => {
|
|
124
|
+
state.status = "rejected"
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
.addCase(addContact.fulfilled, (state, action) => {
|
|
128
|
+
const newContact = action.payload
|
|
129
|
+
const newContacts = {...state.values}
|
|
130
|
+
newContacts[action.payload.id] = newContact
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
.addCase(updateContact.fulfilled, (state, action) => {
|
|
134
|
+
state.values[action.payload.contactId] = { ...state.values[action.payload.contactId], ...action.payload.attributes };
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
.addCase(deleteContact.fulfilled, (state, action) => {
|
|
138
|
+
const contactIdToDelete = action.payload;
|
|
139
|
+
const newContacts = { ...state, values: { ...state.values } };
|
|
140
|
+
delete newContacts.values[contactIdToDelete];
|
|
141
|
+
return newContacts;
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
export const {setContacts, setLastContact, addContacts} = contactsSlice.actions;
|
|
147
|
+
|
|
148
148
|
export default contactsSlice.reducer;
|
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
import {where} from "firebase/firestore";
|
|
2
|
-
import {useLazyLoadQueryList} from "../../hooks";
|
|
3
|
-
import { useAppDispatch } from "../../reduxHooks";
|
|
4
|
-
import { Contact, UserData } from "../../typeDefinitions";
|
|
5
|
-
import { addContact, deleteContact, updateContact } from "./contactsSlice";
|
|
6
|
-
|
|
7
|
-
export function useContacts({user}: {user: UserData}){
|
|
8
|
-
const dispatch = useAppDispatch()
|
|
9
|
-
const {items, loadMore, loadMoreIcon, reset} = useLazyLoadQueryList({path: "contacts", constraints: where("uid", "==", user?.id), number: 5});
|
|
10
|
-
|
|
11
|
-
// const contacts = user?.product === "institutes" && user.userType === "Students" ?
|
|
12
|
-
// useInstituteStudentSelector((state) => state.contacts) :
|
|
13
|
-
// user?.product === "students" ? useStudentSelector((state) => state.contacts) : undefined;
|
|
14
|
-
// const [loadMoreIcon, setLoadMoreIcon] = useState<boolean>(false);
|
|
15
|
-
// const firebaseQuery = new FirebaseQuery()
|
|
16
|
-
// const dispatch = user?.product === "institutes" && user.userType === "Students" ?
|
|
17
|
-
// useInstituteStudentDispatch() :
|
|
18
|
-
// user?.product === "students" ? useStudentDispatch() : undefined;
|
|
19
|
-
|
|
20
|
-
// if (!dispatch || !contacts) {
|
|
21
|
-
// throw new Error("Cannot access featture.");
|
|
22
|
-
// }
|
|
23
|
-
|
|
24
|
-
// const reset = () => {
|
|
25
|
-
// dispatch(setContacts({}))
|
|
26
|
-
// dispatch(setLastContact(undefined));
|
|
27
|
-
// };
|
|
28
|
-
|
|
29
|
-
// const loadMore = async () => {
|
|
30
|
-
// setLoadMoreIcon(true);
|
|
31
|
-
// let formattedConstraints:QueryConstraint[] = [];
|
|
32
|
-
|
|
33
|
-
// if (constraints) {
|
|
34
|
-
// formattedConstraints = (Array.isArray(constraints) ? [...constraints, limit(number)] : [constraints, limit(number)]);
|
|
35
|
-
// }
|
|
36
|
-
// if (contacts.lastContact) {
|
|
37
|
-
// formattedConstraints.push(startAfter(contacts.lastContact));
|
|
38
|
-
// }
|
|
39
|
-
// const documents = await firebaseQuery.getDocsWhere("contacts", formattedConstraints, true) as QuerySnapshot<DocumentData>;
|
|
40
|
-
// const lastContact = documents.docs[documents.docs.length - 1];
|
|
41
|
-
// dispatch(setLastContact(lastContact))
|
|
42
|
-
// console.log("docs", Object.entries(documents.docs))
|
|
43
|
-
// dispatch(setContacts({
|
|
44
|
-
// ...contacts,
|
|
45
|
-
// ...Object.fromEntries(
|
|
46
|
-
// documents.docs.map(doc => [doc.id, {...doc.data(), docPath: doc.ref}])
|
|
47
|
-
// )
|
|
48
|
-
// }));
|
|
49
|
-
|
|
50
|
-
// setLoadMoreIcon(false);
|
|
51
|
-
// };
|
|
52
|
-
|
|
53
|
-
// useEffect(() => {
|
|
54
|
-
// loadMore();
|
|
55
|
-
// }, []);
|
|
56
|
-
|
|
57
|
-
const addContactForm = async (contactForm: Contact) => {
|
|
58
|
-
if (!user?.id) return
|
|
59
|
-
dispatch(addContact({contactForm: contactForm, userId: user.id}))
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const updateContactForm = async (contactId: string, attributes: any) => {
|
|
63
|
-
dispatch(updateContact({contactId: contactId, attributes: attributes}))
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const deleteContactForm = async (contactId: string) => {
|
|
67
|
-
dispatch(deleteContact({contactId: contactId}))
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return ({...{updateContactForm, addContactForm, deleteContactForm, contacts: items, loadMore, loadMoreIcon, reset}});
|
|
72
|
-
|
|
73
|
-
};
|
|
1
|
+
import {where} from "firebase/firestore";
|
|
2
|
+
import {useLazyLoadQueryList} from "../../hooks";
|
|
3
|
+
import { useAppDispatch } from "../../reduxHooks";
|
|
4
|
+
import { Contact, UserData } from "../../typeDefinitions";
|
|
5
|
+
import { addContact, deleteContact, updateContact } from "./contactsSlice";
|
|
6
|
+
|
|
7
|
+
export function useContacts({user}: {user: UserData}){
|
|
8
|
+
const dispatch = useAppDispatch()
|
|
9
|
+
const {items, loadMore, loadMoreIcon, reset} = useLazyLoadQueryList({path: "contacts", constraints: where("uid", "==", user?.id), number: 5});
|
|
10
|
+
|
|
11
|
+
// const contacts = user?.product === "institutes" && user.userType === "Students" ?
|
|
12
|
+
// useInstituteStudentSelector((state) => state.contacts) :
|
|
13
|
+
// user?.product === "students" ? useStudentSelector((state) => state.contacts) : undefined;
|
|
14
|
+
// const [loadMoreIcon, setLoadMoreIcon] = useState<boolean>(false);
|
|
15
|
+
// const firebaseQuery = new FirebaseQuery()
|
|
16
|
+
// const dispatch = user?.product === "institutes" && user.userType === "Students" ?
|
|
17
|
+
// useInstituteStudentDispatch() :
|
|
18
|
+
// user?.product === "students" ? useStudentDispatch() : undefined;
|
|
19
|
+
|
|
20
|
+
// if (!dispatch || !contacts) {
|
|
21
|
+
// throw new Error("Cannot access featture.");
|
|
22
|
+
// }
|
|
23
|
+
|
|
24
|
+
// const reset = () => {
|
|
25
|
+
// dispatch(setContacts({}))
|
|
26
|
+
// dispatch(setLastContact(undefined));
|
|
27
|
+
// };
|
|
28
|
+
|
|
29
|
+
// const loadMore = async () => {
|
|
30
|
+
// setLoadMoreIcon(true);
|
|
31
|
+
// let formattedConstraints:QueryConstraint[] = [];
|
|
32
|
+
|
|
33
|
+
// if (constraints) {
|
|
34
|
+
// formattedConstraints = (Array.isArray(constraints) ? [...constraints, limit(number)] : [constraints, limit(number)]);
|
|
35
|
+
// }
|
|
36
|
+
// if (contacts.lastContact) {
|
|
37
|
+
// formattedConstraints.push(startAfter(contacts.lastContact));
|
|
38
|
+
// }
|
|
39
|
+
// const documents = await firebaseQuery.getDocsWhere("contacts", formattedConstraints, true) as QuerySnapshot<DocumentData>;
|
|
40
|
+
// const lastContact = documents.docs[documents.docs.length - 1];
|
|
41
|
+
// dispatch(setLastContact(lastContact))
|
|
42
|
+
// console.log("docs", Object.entries(documents.docs))
|
|
43
|
+
// dispatch(setContacts({
|
|
44
|
+
// ...contacts,
|
|
45
|
+
// ...Object.fromEntries(
|
|
46
|
+
// documents.docs.map(doc => [doc.id, {...doc.data(), docPath: doc.ref}])
|
|
47
|
+
// )
|
|
48
|
+
// }));
|
|
49
|
+
|
|
50
|
+
// setLoadMoreIcon(false);
|
|
51
|
+
// };
|
|
52
|
+
|
|
53
|
+
// useEffect(() => {
|
|
54
|
+
// loadMore();
|
|
55
|
+
// }, []);
|
|
56
|
+
|
|
57
|
+
const addContactForm = async (contactForm: Contact) => {
|
|
58
|
+
if (!user?.id) return
|
|
59
|
+
dispatch(addContact({contactForm: contactForm, userId: user.id}))
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const updateContactForm = async (contactId: string, attributes: any) => {
|
|
63
|
+
dispatch(updateContact({contactId: contactId, attributes: attributes}))
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const deleteContactForm = async (contactId: string) => {
|
|
67
|
+
dispatch(deleteContact({contactId: contactId}))
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
return ({...{updateContactForm, addContactForm, deleteContactForm, contacts: items, loadMore, loadMoreIcon, reset}});
|
|
72
|
+
|
|
73
|
+
};
|