import { DeanApproval } from "@/data/deanApproval"; import { Action } from "@/state/actions"; import { momentSerializationTransformer } from "@/serialization"; import moment from "moment"; import { ReceiveSubmissionApproveAction, ReceiveSubmissionDeclineAction, SubmissionAction } from "@/state/actions/submission"; export type SubmissionStatus = "draft" | "awaiting" | "accepted" | "declined"; export type SubmissionState = { accepted: boolean; sent: boolean; sentOn: string | null; declined: boolean; comment: string | null; } export type MayRequireDeanApproval = { requiredDeanApprovals: DeanApproval[], } export const defaultSubmissionState: SubmissionState = { accepted: false, sent: false, sentOn: null, declined: false, comment: null, } export const defaultDeanApprovalsState: MayRequireDeanApproval = { requiredDeanApprovals: [], } export const getSubmissionStatus = ({ accepted, declined, sent }: SubmissionState): SubmissionStatus => { switch (true) { case !sent: return "draft"; case sent && accepted: return "accepted" case sent && declined: return "declined" case sent && (!accepted && !declined): return "awaiting" default: throw new Error("Invalid submission state " + JSON.stringify({ accepted, declined, sent })); } } export function createSubmissionReducer(mapping: { [TAction in keyof TActionType]: SubmissionAction }) { return (state: TState, action: TAction) => { const mappedAction = mapping[action.type as keyof TActionType]; switch (mappedAction) { case SubmissionAction.Approve: return { ...state, accepted: true, declined: false, comment: (action as ReceiveSubmissionApproveAction).comment, } case SubmissionAction.Decline: return { ...state, accepted: false, declined: true, comment: (action as ReceiveSubmissionDeclineAction).comment, } case SubmissionAction.Send: return { ...state, sent: true, sentOn: momentSerializationTransformer.transform(moment()), accepted: false, declined: false, comment: null, } default: return state; } } }