import {createSlice, createAsyncThunk} from "@reduxjs/toolkit"; import FirebaseQuery from "../../../firebase/firebaseQuery"; import { PlacementState } from "../types"; import { StudentPlacementData } from "../../../typeDefinitions"; export interface UpcomingPlacementState extends PlacementState { upcoming?: StudentPlacementData; } const initialState: UpcomingPlacementState = { status: "", lastPlacement: undefined, upcoming: undefined, values: {} } export const updateUpcomingStudentPlacement = createAsyncThunk( "upcomingStudentPlacements/updateStudentPlacement", async ({ placementId, attributes }:{placementId: string, attributes: Partial}, {rejectWithValue}) => { const firebaseQuery = new FirebaseQuery(); try { await firebaseQuery.update(["placements", placementId], attributes); return {attributes, placementId} } catch(error) { return rejectWithValue(error); } } ); export const deleteUpcomingStudentPlacement = createAsyncThunk( "upcomingStudentPlacements/deleteStudentPlacement", async ({placementId}:{placementId: string}, { rejectWithValue}) => { const firebaseQuery = new FirebaseQuery(); try { await firebaseQuery.delete(["placements", placementId]); return placementId } catch(error) { return rejectWithValue(error); } } ); export const upcomingStudentsPlacementsSlice = createSlice({ name: "upcomingStudentsPlacements", initialState, reducers: { setUpcomingStudentPlacements: (state, action) => { state.values = action.payload }, setUpcomingStatus: (state, action) => { state.status = action.payload }, setUpcoming: (state, action) => { state.upcoming = action.payload }, setUpcomingIsDraft: (state, action) => { const {placementId, draft} = action.payload state.values[placementId].draft = draft }, addUpcomingStudentPlacements: (state, action) => { state.values = {...state.values, ...action.payload} }, addUpcomingStudentPlacement: (state, action) => { const {placement, placementId} = action.payload const newPlacements = {...state.values}; newPlacements[placementId] = placement; state.values = Object.fromEntries(Object.entries(newPlacements).sort(([, a], [, b]) => b.startDate > a.endDate ? 1 : -1)); }, setLastUpcomingPlacement: (state, action) => { state.lastPlacement = action.payload } }, extraReducers(builder){ builder .addCase(updateUpcomingStudentPlacement.fulfilled, (state, action) => { const {attributes, placementId} = action.payload if (!placementId) return state.values[placementId] = {...state.values[placementId], ...attributes}; }) .addCase(deleteUpcomingStudentPlacement.fulfilled, (state, action) => { const placementIdToDelete = action.payload; const newPlacements = { ...state, values: { ...state.values } }; delete newPlacements.values[placementIdToDelete]; return newPlacements; }) } }) export const {addUpcomingStudentPlacements, addUpcomingStudentPlacement, setUpcomingStudentPlacements, setLastUpcomingPlacement, setUpcoming, setUpcomingStatus, setUpcomingIsDraft} = upcomingStudentsPlacementsSlice.actions export default upcomingStudentsPlacementsSlice.reducer;