Add insurance step
This commit is contained in:
parent
943d83cd26
commit
a78f5d365e
@ -11,6 +11,7 @@ export type Deadlines = {
|
|||||||
proposal?: Moment;
|
proposal?: Moment;
|
||||||
personalPlan?: Moment;
|
personalPlan?: Moment;
|
||||||
report?: Moment;
|
report?: Moment;
|
||||||
|
insurance?: Moment;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEditionDeadlines(edition: Edition): Deadlines {
|
export function getEditionDeadlines(edition: Edition): Deadlines {
|
||||||
|
@ -11,12 +11,15 @@ import { Deadlines, Edition, getEditionDeadlines } from "@/data/edition";
|
|||||||
import { Step } from "@/components";
|
import { Step } from "@/components";
|
||||||
import { ProposalStep } from "@/pages/steps/proposal";
|
import { ProposalStep } from "@/pages/steps/proposal";
|
||||||
import { PlanStep } from "@/pages/steps/plan";
|
import { PlanStep } from "@/pages/steps/plan";
|
||||||
|
import { InsuranceStep } from "@/pages/steps/insurance";
|
||||||
|
import { InsuranceState } from "@/state/reducer/insurance";
|
||||||
|
|
||||||
export const MainPage = () => {
|
export const MainPage = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const student = useSelector<AppState, Student | null>(state => state.student);
|
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 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]);
|
const missingStudentData = useMemo(() => student ? getMissingStudentData(student) : [], [student]);
|
||||||
|
|
||||||
@ -39,7 +42,7 @@ export const MainPage = () => {
|
|||||||
</Step>
|
</Step>
|
||||||
<ProposalStep />
|
<ProposalStep />
|
||||||
<PlanStep />
|
<PlanStep />
|
||||||
<Step label={ t('steps.insurance.header') }/>
|
{ insurance.required && <InsuranceStep /> }
|
||||||
<Step label={ t('steps.report.header') } until={ deadlines.report }/>
|
<Step label={ t('steps.report.header') } until={ deadlines.report }/>
|
||||||
<Step label={ t('steps.grade.header') }/>
|
<Step label={ t('steps.grade.header') }/>
|
||||||
</Stepper>
|
</Stepper>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { getSubmissionStatus, SubmissionState, SubmissionStatus } from "@/state/reducer/submission";
|
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 { createStyles, makeStyles } from "@material-ui/core/styles";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { CommentQuestion } from "mdi-material-ui/index";
|
||||||
|
|
||||||
export const getColorByStatus = (status: SubmissionStatus, theme: Theme) => {
|
export const getColorByStatus = (status: SubmissionStatus, theme: Theme) => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
@ -44,3 +45,9 @@ export const Status = ({ submission } : SubmissionStatusProps) => {
|
|||||||
|
|
||||||
return <span className={ classes.foreground }>{ t(`submission.status.${ status }`) }</span>;
|
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>
|
||||||
|
}
|
||||||
|
27
src/pages/steps/insurance.tsx
Normal file
27
src/pages/steps/insurance.tsx
Normal 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>
|
||||||
|
}
|
@ -3,14 +3,14 @@ import { AppState } from "@/state/reducer";
|
|||||||
import { getSubmissionStatus, SubmissionState, SubmissionStatus } from "@/state/reducer/submission";
|
import { getSubmissionStatus, SubmissionState, SubmissionStatus } from "@/state/reducer/submission";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Box, Button, ButtonProps, StepProps } from "@material-ui/core";
|
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 { route } from "@/routing";
|
||||||
import { Link as RouterLink } from "react-router-dom";
|
import { Link as RouterLink } from "react-router-dom";
|
||||||
import { Actions, Step } from "@/components";
|
import { Actions, Step } from "@/components";
|
||||||
import React, { HTMLProps } from "react";
|
import React, { HTMLProps } from "react";
|
||||||
import { Alert, AlertTitle } from "@material-ui/lab";
|
import { Alert, AlertTitle } from "@material-ui/lab";
|
||||||
import { Deadlines, Edition, getEditionDeadlines } from "@/data/edition";
|
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";
|
import { Description as DescriptionIcon } from "@material-ui/icons";
|
||||||
|
|
||||||
const PlanActions = () => {
|
const PlanActions = () => {
|
||||||
@ -30,9 +30,6 @@ const PlanActions = () => {
|
|||||||
{ t('steps.plan.template') }
|
{ t('steps.plan.template') }
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
const ContactAction = (props: ButtonProps) =>
|
|
||||||
<Button startIcon={ <CommentQuestion/> } variant="outlined" color="primary" { ...props }>{ t('contact') }</Button>
|
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case "awaiting":
|
case "awaiting":
|
||||||
return <Actions>
|
return <Actions>
|
||||||
|
@ -10,8 +10,8 @@ import { Deadlines, Edition, getEditionDeadlines } from "@/data/edition";
|
|||||||
import { Actions, Step } from "@/components";
|
import { Actions, Step } from "@/components";
|
||||||
import { route } from "@/routing";
|
import { route } from "@/routing";
|
||||||
import { Link as RouterLink } from "react-router-dom";
|
import { Link as RouterLink } from "react-router-dom";
|
||||||
import { ClipboardEditOutline, CommentQuestion, FileFind } from "mdi-material-ui/index";
|
import { ClipboardEditOutline, FileFind } from "mdi-material-ui/index";
|
||||||
import { Status } from "@/pages/steps/common";
|
import { ContactAction, Status } from "@/pages/steps/common";
|
||||||
|
|
||||||
const ProposalActions = () => {
|
const ProposalActions = () => {
|
||||||
const status = useSelector<AppState, SubmissionStatus>(state => getSubmissionStatus(state.proposal));
|
const status = useSelector<AppState, SubmissionStatus>(state => getSubmissionStatus(state.proposal));
|
||||||
@ -26,9 +26,6 @@ const ProposalActions = () => {
|
|||||||
{ children }
|
{ children }
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
const ContactAction = (props: ButtonProps) =>
|
|
||||||
<Button startIcon={ <CommentQuestion/> } variant="outlined" color="primary" { ...props }>{ t('contact') }</Button>
|
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case "awaiting":
|
case "awaiting":
|
||||||
return <Actions>
|
return <Actions>
|
||||||
@ -42,7 +39,7 @@ const ProposalActions = () => {
|
|||||||
case "declined":
|
case "declined":
|
||||||
return <Actions>
|
return <Actions>
|
||||||
<FormAction>{ t('fix-errors') }</FormAction>
|
<FormAction>{ t('fix-errors') }</FormAction>
|
||||||
<ContactAction/>
|
<ContactAction />
|
||||||
</Actions>
|
</Actions>
|
||||||
case "draft":
|
case "draft":
|
||||||
return <Actions>
|
return <Actions>
|
||||||
|
@ -6,6 +6,7 @@ import { Dispatch } from "react";
|
|||||||
|
|
||||||
import { useDispatch as useReduxDispatch } from "react-redux";
|
import { useDispatch as useReduxDispatch } from "react-redux";
|
||||||
import { InternshipPlanAction, InternshipPlanActions } from "@/state/actions/plan";
|
import { InternshipPlanAction, InternshipPlanActions } from "@/state/actions/plan";
|
||||||
|
import { InsuranceAction, InsuranceActions } from "@/state/actions/insurance";
|
||||||
|
|
||||||
export * from "./base"
|
export * from "./base"
|
||||||
export * from "./edition"
|
export * from "./edition"
|
||||||
@ -14,9 +15,9 @@ export * from "./student"
|
|||||||
export * from "./proposal"
|
export * from "./proposal"
|
||||||
export * from "./plan"
|
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 type Actions = typeof Actions;
|
||||||
|
|
||||||
export const useDispatch = () => useReduxDispatch<Dispatch<Action>>()
|
export const useDispatch = () => useReduxDispatch<Dispatch<Action>>()
|
||||||
|
12
src/state/actions/insurance.ts
Normal file
12
src/state/actions/insurance.ts
Normal 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;
|
@ -5,6 +5,7 @@ import editionReducer from "@/state/reducer/edition";
|
|||||||
import settingsReducer from "@/state/reducer/settings";
|
import settingsReducer from "@/state/reducer/settings";
|
||||||
import internshipProposalReducer from "@/state/reducer/proposal";
|
import internshipProposalReducer from "@/state/reducer/proposal";
|
||||||
import internshipPlanReducer from "@/state/reducer/plan";
|
import internshipPlanReducer from "@/state/reducer/plan";
|
||||||
|
import { insuranceReducer } from "@/state/reducer/insurance";
|
||||||
|
|
||||||
const rootReducer = combineReducers({
|
const rootReducer = combineReducers({
|
||||||
student: studentReducer,
|
student: studentReducer,
|
||||||
@ -12,6 +13,7 @@ const rootReducer = combineReducers({
|
|||||||
settings: settingsReducer,
|
settings: settingsReducer,
|
||||||
proposal: internshipProposalReducer,
|
proposal: internshipProposalReducer,
|
||||||
plan: internshipPlanReducer,
|
plan: internshipPlanReducer,
|
||||||
|
insurance: insuranceReducer,
|
||||||
})
|
})
|
||||||
|
|
||||||
export type AppState = ReturnType<typeof rootReducer>;
|
export type AppState = ReturnType<typeof rootReducer>;
|
||||||
|
26
src/state/reducer/insurance.ts
Normal file
26
src/state/reducer/insurance.ts
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -95,5 +95,7 @@ steps:
|
|||||||
header: "Ocena z praktyki"
|
header: "Ocena z praktyki"
|
||||||
insurance:
|
insurance:
|
||||||
header: "Ubezpieczenie NNW"
|
header: "Ubezpieczenie NNW"
|
||||||
|
instructions: >
|
||||||
|
papierki do podpisania...
|
||||||
|
|
||||||
contact-coordinator: "Skontaktuj się z koordynatorem"
|
contact-coordinator: "Skontaktuj się z koordynatorem"
|
||||||
|
Loading…
Reference in New Issue
Block a user