Add insurance step

This commit is contained in:
Kacper Donat 2020-08-05 22:50:57 +02:00
parent 0e1ef4411a
commit e7831cf1e5
11 changed files with 90 additions and 15 deletions

View File

@ -11,6 +11,7 @@ export type Deadlines = {
proposal?: Moment;
personalPlan?: Moment;
report?: Moment;
insurance?: Moment;
}
export function getEditionDeadlines(edition: Edition): Deadlines {

View File

@ -11,12 +11,15 @@ import { Deadlines, Edition, getEditionDeadlines } from "@/data/edition";
import { Step } from "@/components";
import { ProposalStep } from "@/pages/steps/proposal";
import { PlanStep } from "@/pages/steps/plan";
import { InsuranceStep } from "@/pages/steps/insurance";
import { InsuranceState } from "@/state/reducer/insurance";
export const MainPage = () => {
const { t } = useTranslation();
const student = useSelector<AppState, Student | null>(state => state.student);
const deadlines = useSelector<AppState, Deadlines>(state => getEditionDeadlines(state.edition as Edition)); // edition cannot be null at this point
const insurance = useSelector<AppState, InsuranceState>(root => root.insurance);
const missingStudentData = useMemo(() => student ? getMissingStudentData(student) : [], [student]);
@ -39,7 +42,7 @@ export const MainPage = () => {
</Step>
<ProposalStep />
<PlanStep />
<Step label={ t('steps.insurance.header') }/>
{ insurance.required && <InsuranceStep /> }
<Step label={ t('steps.report.header') } until={ deadlines.report }/>
<Step label={ t('steps.grade.header') }/>
</Stepper>

View File

@ -1,8 +1,9 @@
import { getSubmissionStatus, SubmissionState, SubmissionStatus } from "@/state/reducer/submission";
import { Theme } from "@material-ui/core";
import { Button, ButtonProps, Theme } from "@material-ui/core";
import { createStyles, makeStyles } from "@material-ui/core/styles";
import { useTranslation } from "react-i18next";
import React from "react";
import { CommentQuestion } from "mdi-material-ui/index";
export const getColorByStatus = (status: SubmissionStatus, theme: Theme) => {
switch (status) {
@ -44,3 +45,9 @@ export const Status = ({ submission } : SubmissionStatusProps) => {
return <span className={ classes.foreground }>{ t(`submission.status.${ status }`) }</span>;
}
export const ContactAction = (props: ButtonProps) => {
const { t } = useTranslation();
return <Button startIcon={ <CommentQuestion/> } variant="outlined" color="primary" { ...props }>{ t('contact') }</Button>
}

View File

@ -0,0 +1,27 @@
import { useSelector } from "react-redux";
import { AppState } from "@/state/reducer";
import { InsuranceState } from "@/state/reducer/insurance";
import { Actions, Step } from "@/components";
import { useTranslation } from "react-i18next";
import React from "react";
import { Edition, getEditionDeadlines } from "@/data/edition";
import { Moment } from "moment";
import { ContactAction } from "@/pages/steps/common";
export const InsuranceStep = () => {
const insurance = useSelector<AppState, InsuranceState>(root => root.insurance);
const deadline = useSelector<AppState, Moment | undefined>(state => getEditionDeadlines(state.edition as Edition).insurance); // edition cannot be null at this point
const { t } = useTranslation();
// we don't want to show this step unless it's required
if (!insurance.required) {
return null;
}
return <Step label={ t("steps.insurance.header") } until={ deadline } completed={ insurance.signed } active={ !insurance.signed }>
<p>{ t(`steps.insurance.instructions`) }</p>
<Actions>
<ContactAction />
</Actions>
</Step>
}

View File

@ -3,14 +3,14 @@ import { AppState } from "@/state/reducer";
import { getSubmissionStatus, SubmissionState, SubmissionStatus } from "@/state/reducer/submission";
import { useTranslation } from "react-i18next";
import { Box, Button, ButtonProps, StepProps } from "@material-ui/core";
import { CommentQuestion, FileDownloadOutline, FileUploadOutline } from "mdi-material-ui/index";
import { FileDownloadOutline, FileUploadOutline } from "mdi-material-ui/index";
import { route } from "@/routing";
import { Link as RouterLink } from "react-router-dom";
import { Actions, Step } from "@/components";
import React, { HTMLProps } from "react";
import { Alert, AlertTitle } from "@material-ui/lab";
import { Deadlines, Edition, getEditionDeadlines } from "@/data/edition";
import { Status } from "@/pages/steps/common";
import { ContactAction, Status } from "@/pages/steps/common";
import { Description as DescriptionIcon } from "@material-ui/icons";
const PlanActions = () => {
@ -30,9 +30,6 @@ const PlanActions = () => {
{ t('steps.plan.template') }
</Button>
const ContactAction = (props: ButtonProps) =>
<Button startIcon={ <CommentQuestion/> } variant="outlined" color="primary" { ...props }>{ t('contact') }</Button>
switch (status) {
case "awaiting":
return <Actions>

View File

@ -10,8 +10,8 @@ import { Deadlines, Edition, getEditionDeadlines } from "@/data/edition";
import { Actions, Step } from "@/components";
import { route } from "@/routing";
import { Link as RouterLink } from "react-router-dom";
import { ClipboardEditOutline, CommentQuestion, FileFind } from "mdi-material-ui/index";
import { Status } from "@/pages/steps/common";
import { ClipboardEditOutline, FileFind } from "mdi-material-ui/index";
import { ContactAction, Status } from "@/pages/steps/common";
const ProposalActions = () => {
const status = useSelector<AppState, SubmissionStatus>(state => getSubmissionStatus(state.proposal));
@ -26,9 +26,6 @@ const ProposalActions = () => {
{ children }
</Button>
const ContactAction = (props: ButtonProps) =>
<Button startIcon={ <CommentQuestion/> } variant="outlined" color="primary" { ...props }>{ t('contact') }</Button>
switch (status) {
case "awaiting":
return <Actions>
@ -42,7 +39,7 @@ const ProposalActions = () => {
case "declined":
return <Actions>
<FormAction>{ t('fix-errors') }</FormAction>
<ContactAction/>
<ContactAction />
</Actions>
case "draft":
return <Actions>

View File

@ -6,6 +6,7 @@ import { Dispatch } from "react";
import { useDispatch as useReduxDispatch } from "react-redux";
import { InternshipPlanAction, InternshipPlanActions } from "@/state/actions/plan";
import { InsuranceAction, InsuranceActions } from "@/state/actions/insurance";
export * from "./base"
export * from "./edition"
@ -14,9 +15,9 @@ export * from "./student"
export * from "./proposal"
export * from "./plan"
export type Action = StudentAction | EditionAction | SettingsAction | InternshipProposalAction | InternshipPlanAction;
export type Action = StudentAction | EditionAction | SettingsAction | InternshipProposalAction | InternshipPlanAction | InsuranceAction;
export const Actions = { ...StudentActions, ...EditionActions, ...SettingActions, ...InternshipProposalActions, ...InternshipPlanActions }
export const Actions = { ...StudentActions, ...EditionActions, ...SettingActions, ...InternshipProposalActions, ...InternshipPlanActions, ...InsuranceActions }
export type Actions = typeof Actions;
export const useDispatch = () => useReduxDispatch<Dispatch<Action>>()

View File

@ -0,0 +1,12 @@
import { Action } from "@/state/actions/base";
import { InsuranceState } from "@/state/reducer/insurance";
export enum InsuranceActions {
Signed = "RECEIVE_INSURANCE_SIGN",
Update = "RECEIVE_INSURANCE_UPDATE",
}
export type InsuranceSigned = Action<InsuranceActions.Signed>;
export type InsuranceUpdate = Action<InsuranceActions.Update> & Partial<InsuranceState>;
export type InsuranceAction = InsuranceSigned | InsuranceUpdate;

View File

@ -5,6 +5,7 @@ import editionReducer from "@/state/reducer/edition";
import settingsReducer from "@/state/reducer/settings";
import internshipProposalReducer from "@/state/reducer/proposal";
import internshipPlanReducer from "@/state/reducer/plan";
import { insuranceReducer } from "@/state/reducer/insurance";
const rootReducer = combineReducers({
student: studentReducer,
@ -12,6 +13,7 @@ const rootReducer = combineReducers({
settings: settingsReducer,
proposal: internshipProposalReducer,
plan: internshipPlanReducer,
insurance: insuranceReducer,
})
export type AppState = ReturnType<typeof rootReducer>;

View File

@ -0,0 +1,26 @@
import { Reducer } from "react";
import { InsuranceAction, InsuranceActions } from "@/state/actions/insurance";
export type InsuranceState = {
required: boolean;
signed: boolean;
/// other data?
}
const initialInsuranceState: InsuranceState = {
required: false,
signed: false,
}
export const insuranceReducer: Reducer<InsuranceState, InsuranceAction> = (state = initialInsuranceState, action) => {
const { type, ...payload } = action;
switch (action.type) {
case InsuranceActions.Signed:
return { ...state, signed: true }
case InsuranceActions.Update:
return { ...state, ...payload }
default:
return state;
}
}

View File

@ -95,5 +95,7 @@ steps:
header: "Ocena z praktyki"
insurance:
header: "Ubezpieczenie NNW"
instructions: >
papierki do podpisania...
contact-coordinator: "Skontaktuj się z koordynatorem"