diff --git a/.build/deploy.sh b/.build/deploy.sh
index 36f34bb..89c7bba 100755
--- a/.build/deploy.sh
+++ b/.build/deploy.sh
@@ -2,5 +2,6 @@ BUILD_PATH=$1
 DEPLOY_PATH=$2
 
 # copy all dist files to deploy path
+rsync -avz $BUILD_PATH/public/* $DEPLOY_PATH
 rsync -avz $BUILD_PATH/build/* $DEPLOY_PATH
 
diff --git a/src/components/actions.tsx b/src/components/actions.tsx
index 5fdb03d..34357c3 100644
--- a/src/components/actions.tsx
+++ b/src/components/actions.tsx
@@ -1,14 +1,8 @@
 import React, { HTMLProps } from "react";
-import { makeStyles } from "@material-ui/core/styles";
+import { useHorizontalSpacing } from "@/styles";
 
 export const Actions = (props: HTMLProps<HTMLDivElement>) => {
-    const classes = makeStyles(theme => ({
-        root: {
-            "& > *": {
-                marginRight: theme.spacing(1)
-            }
-        }
-    }))();
+    const classes = useHorizontalSpacing(1);
 
     return <div className={ classes.root } { ...props }/>
 }
diff --git a/src/components/proposalPreview.tsx b/src/components/proposalPreview.tsx
new file mode 100644
index 0000000..d0b8870
--- /dev/null
+++ b/src/components/proposalPreview.tsx
@@ -0,0 +1,95 @@
+import { Internship, internshipTypeLabels } from "@/data";
+import React from "react";
+import { Button, Paper, PaperProps, Typography, TypographyProps } from "@material-ui/core";
+import { useTranslation } from "react-i18next";
+import { createStyles, makeStyles } from "@material-ui/core/styles";
+import classNames from "classnames";
+import { Link as RouterLink } from "react-router-dom";
+import { route } from "@/routing";
+import { Actions } from "@/components/actions";
+import { useVerticalSpacing } from "@/styles";
+import moment from "moment";
+
+export type ProposalPreviewProps = {
+    proposal: Internship;
+}
+
+const Label = ({ children }: TypographyProps) => {
+    return <Typography variant="subtitle2" className="proposal__header">{ children }</Typography>
+}
+
+const useSectionStyles = makeStyles(theme => createStyles({
+    root: {
+        padding: theme.spacing(2),
+    }
+}))
+
+const Section = ({ children, ...props }: PaperProps) => {
+    const classes = useSectionStyles();
+
+    return <Paper {...props} className={ classNames(classes.root, props.className ) }>
+        { children }
+    </Paper>
+}
+
+export const ProposalPreview = ({ proposal }: ProposalPreviewProps) => {
+    const { t } = useTranslation();
+
+    const classes = useVerticalSpacing(3);
+
+    const duration = moment.duration(proposal.endDate.diff(proposal.startDate));
+
+    return <div className={ classNames("proposal", classes.root) }>
+        <div>
+            <Typography className="proposal__primary">{ proposal.intern.name } { proposal.intern.surname }</Typography>
+            <Typography className="proposal__secondary">
+                { t('internship.intern.semester', { semester: proposal.intern.semester }) }
+                { ", " }
+                { t('internship.intern.album', { album: proposal.intern.albumNumber }) }
+            </Typography>
+        </div>
+
+        <Section>
+            <Label>{ t('internship.sections.place') }</Label>
+            <Typography className="proposal__primary">
+                { proposal.company.name }
+            </Typography>
+            <Typography className="proposal__secondary">
+                NIP: { proposal.company.nip }
+            </Typography>
+
+            <Label>{ t('internship.office') }</Label>
+            <Typography className="proposal__primary">{ t('internship.address.city', proposal.office.address) }</Typography>
+            <Typography className="proposal__secondary">{ t('internship.address.street', proposal.office.address) }</Typography>
+        </Section>
+
+        <Section>
+            <Label>{ t('internship.sections.kind') }</Label>
+            <Typography className="proposal__primary">{ internshipTypeLabels[proposal.type].label }</Typography>
+        </Section>
+
+        <Section>
+            <Label>{ t('internship.sections.duration') }</Label>
+            <Typography className="proposal__primary">
+                { t('internship.date-range', { start: proposal.startDate, end: proposal.endDate }) }
+            </Typography>
+            <Typography className="proposal__secondary">
+                { t('internship.duration', { duration }) }
+                { ", " }
+                { t('internship.hours', { hours: proposal.hours }) }
+            </Typography>
+        </Section>
+
+        <Section>
+            <Label>{ t('internship.sections.mentor') }</Label>
+            <Typography className="proposal__primary">{ proposal.mentor.name } { proposal.mentor.surname }</Typography>
+            <Typography className="proposal__secondary">{ proposal.mentor.email }, { proposal.mentor.phone }</Typography>
+        </Section>
+
+        <Actions>
+            <Button component={ RouterLink } to={ route("home") } variant="contained" color="primary">
+                { t('go-back') }
+            </Button>
+        </Actions>
+    </div>
+}
diff --git a/src/data/edition.ts b/src/data/edition.ts
index 8a29c94..7fc5438 100644
--- a/src/data/edition.ts
+++ b/src/data/edition.ts
@@ -11,6 +11,7 @@ export type Deadlines = {
     proposal?: Moment;
     personalPlan?: Moment;
     report?: Moment;
+    insurance?: Moment;
 }
 
 export function getEditionDeadlines(edition: Edition): Deadlines {
diff --git a/src/forms/internship.tsx b/src/forms/internship.tsx
index 01b8689..f4d2324 100644
--- a/src/forms/internship.tsx
+++ b/src/forms/internship.tsx
@@ -1,5 +1,18 @@
 import React, { HTMLProps, useEffect, useMemo, useState } from "react";
-import { Button, FormControl, FormHelperText, Grid, Input, InputLabel, TextField, Typography } from "@material-ui/core";
+import {
+    Button,
+    Dialog,
+    DialogActions,
+    DialogContent,
+    DialogContentText,
+    FormControl,
+    FormHelperText,
+    Grid,
+    Input,
+    InputLabel,
+    TextField,
+    Typography
+} from "@material-ui/core";
 import { KeyboardDatePicker as DatePicker } from "@material-ui/pickers";
 import { CompanyForm } from "@/forms/company";
 import { StudentForm } from "@/forms/student";
@@ -46,30 +59,30 @@ const InternshipProgramForm = ({ internship, onChange }: InternshipFormSectionPr
 
     return (
         <Grid container>
-            <Grid item md={4}>
+            <Grid item md={ 4 }>
                 <Autocomplete renderInput={ props => <TextField { ...props } label="Rodzaj praktyki/umowy" fullWidth/> }
                               getOptionLabel={ (option: InternshipType) => internshipTypeLabels[option].label }
-                              renderOption={ (option: InternshipType) => <InternshipTypeItem type={ option } /> }
+                              renderOption={ (option: InternshipType) => <InternshipTypeItem type={ option }/> }
                               options={ Object.values(InternshipType) as InternshipType[] }
                               disableClearable
                               { ...fieldProps("type", (event, value) => value) as any }
                 />
             </Grid>
-            <Grid item md={8}>
-                { internship.type === InternshipType.Other && <TextField label={"Inny - Wprowadź"} fullWidth/> }
+            <Grid item md={ 8 }>
+                { internship.type === InternshipType.Other && <TextField label={ "Inny - Wprowadź" } fullWidth/> }
             </Grid>
-            {/*<Grid item>*/}
-            {/*    <FormGroup>*/}
-            {/*        <FormLabel component="legend" className="subsection-header">Realizowane punkty programu praktyk (minimum 3)</FormLabel>*/}
-            {/*        { course.possibleProgramEntries.map(entry => {*/}
-            {/*            return (*/}
-            {/*                <FormControlLabel label={ entry.description } key={ entry.id }*/}
-            {/*                                  control={ <Checkbox /> }*/}
-            {/*                />*/}
-            {/*            )*/}
-            {/*        }) }*/}
-            {/*    </FormGroup>*/}
-            {/*</Grid>*/}
+            {/*<Grid item>*/ }
+            {/*    <FormGroup>*/ }
+            {/*        <FormLabel component="legend" className="subsection-header">Realizowane punkty programu praktyk (minimum 3)</FormLabel>*/ }
+            {/*        { course.possibleProgramEntries.map(entry => {*/ }
+            {/*            return (*/ }
+            {/*                <FormControlLabel label={ entry.description } key={ entry.id }*/ }
+            {/*                                  control={ <Checkbox /> }*/ }
+            {/*                />*/ }
+            {/*            )*/ }
+            {/*        }) }*/ }
+            {/*    </FormGroup>*/ }
+            {/*</Grid>*/ }
         </Grid>
     )
 }
@@ -84,7 +97,7 @@ const InternshipDurationForm = ({ internship, onChange }: InternshipFormSectionP
     const computedHours = useMemo(() => startDate && endDate && computeWorkingHours(startDate, endDate, workingHours / 5), [startDate, endDate, workingHours]);
 
     const hours = useMemo(() => overrideHours !== null ? overrideHours : computedHours || null, [overrideHours, computedHours]);
-    const weeks = useMemo(() => hours !== null ? Math.floor(hours / 40) : null, [ hours ]);
+    const weeks = useMemo(() => hours !== null ? Math.floor(hours / 40) : null, [hours]);
 
     useEffect(() => onChange({ ...internship, hours }), [hours])
 
@@ -139,7 +152,10 @@ const InternshipDurationForm = ({ internship, onChange }: InternshipFormSectionP
 }
 
 export const InternshipForm: React.FunctionComponent<InternshipFormProps> = props => {
-    const initialInternshipState = useSelector<AppState, Nullable<Internship>>(state => getInternshipProposal(state.proposal) || { ...emptyInternship, intern: sampleStudent });
+    const initialInternshipState = useSelector<AppState, Nullable<Internship>>(state => getInternshipProposal(state.proposal) || {
+        ...emptyInternship,
+        intern: sampleStudent
+    });
 
     const [internship, setInternship] = useState<Nullable<Internship>>(initialInternshipState)
     const { t } = useTranslation();
@@ -147,28 +163,50 @@ export const InternshipForm: React.FunctionComponent<InternshipFormProps> = prop
     const dispatch = useDispatch();
     const history = useHistory();
 
+    const [confirmDialogOpen, setConfirmDialogOpen] = useState<boolean>(false);
+
     const handleSubmit = () => {
+        setConfirmDialogOpen(false);
+
         dispatch({ type: InternshipProposalActions.Send, internship: internship as Internship });
         history.push(route("home"))
     }
 
+    const handleSubmitConfirmation = () => {
+        setConfirmDialogOpen(true);
+    }
+
+    const handleCancel = () => {
+        setConfirmDialogOpen(false);
+    }
+
     return (
         <div className="internship-form">
-            <Typography variant="h3" className="section-header">Dane osoby odbywającej praktykę</Typography>
+            <Typography variant="h3" className="section-header">{ t('internship.sections.intern-info') }</Typography>
             <StudentForm student={ sampleStudent }/>
-            <Typography variant="h3" className="section-header">Rodzaj i program praktyki</Typography>
+            <Typography variant="h3" className="section-header">{ t('internship.sections.kind' )}</Typography>
             <InternshipProgramForm internship={ internship } onChange={ setInternship }/>
-            <Typography variant="h3" className="section-header">Czas trwania praktyki</Typography>
+            <Typography variant="h3" className="section-header">{ t('internship.sections.duration') }</Typography>
             <InternshipDurationForm internship={ internship } onChange={ setInternship }/>
-            <Typography variant="h3" className="section-header">Miejsce odbywania praktyki</Typography>
+            <Typography variant="h3" className="section-header">{ t('internship.sections.place') }</Typography>
             <CompanyForm internship={ internship } onChange={ setInternship }/>
             <Actions>
-                <Button variant="contained" color="primary" onClick={ handleSubmit }>{ t("confirm") }</Button>
+                <Button variant="contained" color="primary" onClick={ handleSubmitConfirmation }>{ t("confirm") }</Button>
 
                 <Button component={ RouterLink } to={ route("home") }>
                     { t('go-back') }
                 </Button>
             </Actions>
+
+            <Dialog open={ confirmDialogOpen } onClose={ handleCancel }>
+                <DialogContent>
+                    <DialogContentText>{ t('forms.internship.send-confirmation') }</DialogContentText>
+                </DialogContent>
+                <DialogActions>
+                    <Button onClick={ handleCancel }>{ t('cancel') }</Button>
+                    <Button color="primary" autoFocus onClick={ handleSubmit }>{ t('confirm') }</Button>
+                </DialogActions>
+            </Dialog>
         </div>
     )
 }
diff --git a/src/forms/plan.tsx b/src/forms/plan.tsx
index 24a8fa7..0c96203 100644
--- a/src/forms/plan.tsx
+++ b/src/forms/plan.tsx
@@ -32,7 +32,7 @@ export const PlanForm = () => {
             </Button>
         </Grid>
         <Grid item>
-            <DropzoneArea acceptedFiles={["image/*", "application/x-pdf"]} filesLimit={ 1 } dropzoneText={ t("dropzone") }/>
+            <DropzoneArea acceptedFiles={["image/*", "application/pdf"]} filesLimit={ 1 } dropzoneText={ t("dropzone") }/>
             <FormHelperText>{ t('forms.plan.dropzone-help') }</FormHelperText>
         </Grid>
         <Grid item>
diff --git a/src/hooks/useProxyState.ts b/src/hooks/useProxyState.ts
index 3dd51fa..87b7945 100644
--- a/src/hooks/useProxyState.ts
+++ b/src/hooks/useProxyState.ts
@@ -1,9 +1,10 @@
-import { Dispatch, SetStateAction, useEffect, useState } from "react";
+import { Dispatch, SetStateAction, useState } from "react";
 
 export function useProxyState<T>(initial: T, setter: (value: T) => void): [T, Dispatch<SetStateAction<T>>] {
     const [value, proxy] = useState<T>(initial);
 
-    useEffect(() => setter(value), [ value ]);
-
-    return [value, proxy];
+    return [value, (newValue: SetStateAction<T>) => {
+        proxy(newValue);
+        setter(typeof newValue === "function" ? (newValue as any)(value) : newValue);
+    }];
 }
diff --git a/src/i18n.ts b/src/i18n.ts
index eb71721..c01bc57 100644
--- a/src/i18n.ts
+++ b/src/i18n.ts
@@ -5,6 +5,7 @@ import I18nextBrowserLanguageDetector from "i18next-browser-languagedetector";
 import "moment/locale/pl"
 import "moment/locale/en-gb"
 import moment, { isDuration, isMoment } from "moment";
+import { convertToRoman } from "@/utils/numbers";
 
 const resources = {
     en: {
@@ -24,6 +25,10 @@ i18n
         interpolation: {
             escapeValue: false,
             format: (value, format, lng) => {
+                if (typeof value === "number" && format == "roman") {
+                    return convertToRoman(value);
+                }
+
                 if (isMoment(value)) {
                     return value.locale(lng || "pl").format(format || "DD MMM YYYY");
                 }
diff --git a/src/pages/index.ts b/src/pages/index.ts
index bb1a4b5..c5f71a3 100644
--- a/src/pages/index.ts
+++ b/src/pages/index.ts
@@ -1,7 +1,3 @@
 export * from "./internship/proposal";
 export * from "./errors/not-found"
 export * from "./main"
-export { ProposalStep } from "@/pages/steps/proposal";
-export { ProposalComment } from "@/pages/steps/proposal";
-export { ProposalActions } from "@/pages/steps/proposal";
-export { ProposalStatus } from "@/pages/steps/proposal";
diff --git a/src/pages/internship/proposal.tsx b/src/pages/internship/proposal.tsx
index e45b4cb..09b8ca8 100644
--- a/src/pages/internship/proposal.tsx
+++ b/src/pages/internship/proposal.tsx
@@ -4,9 +4,15 @@ import { Link as RouterLink } from "react-router-dom";
 import { route } from "@/routing";
 import { InternshipForm } from "@/forms/internship";
 import React from "react";
-import { ProposalComment } from "@/pages";
+import { ProposalComment } from "@/pages/steps/proposal";
+import { useTranslation } from "react-i18next";
+import { ProposalPreview } from "@/components/proposalPreview";
+import { useSelector } from "react-redux";
+import { Internship } from "@/data";
+import { AppState } from "@/state/reducer";
+import { internshipSerializationTransformer } from "@/serialization";
 
-export const InternshipProposalPage = () => {
+export const InternshipProposalFormPage = () => {
     return <Page title="Zgłoszenie praktyki">
         <Page.Header maxWidth="md">
             <Page.Breadcrumbs>
@@ -22,4 +28,23 @@ export const InternshipProposalPage = () => {
     </Page>
 }
 
-export default InternshipProposalPage;
+export const InternshipProposalPreviewPage = () => {
+    const { t } = useTranslation();
+    const proposal = useSelector<AppState, Internship | null>(state => state.proposal.proposal && internshipSerializationTransformer.reverseTransform(state.proposal.proposal));
+
+    return <Page title={ t("") }>
+        <Page.Header maxWidth="md">
+            <Page.Breadcrumbs>
+                <Link component={ RouterLink } to={ route("home") }>Moja praktyka</Link>
+                <Typography color="textPrimary">Podgląd zgłoszenia</Typography>
+            </Page.Breadcrumbs>
+            <Page.Title>Moje zgłoszenie</Page.Title>
+        </Page.Header>
+        <Container maxWidth={ "md" }>
+            <ProposalComment />
+            { proposal && <ProposalPreview proposal={ proposal } /> }
+        </Container>
+    </Page>
+}
+
+export default InternshipProposalFormPage;
diff --git a/src/pages/main.tsx b/src/pages/main.tsx
index 3ddcfef..5d2da88 100644
--- a/src/pages/main.tsx
+++ b/src/pages/main.tsx
@@ -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>
diff --git a/src/pages/steps/common.tsx b/src/pages/steps/common.tsx
index 261ba52..58fdb8e 100644
--- a/src/pages/steps/common.tsx
+++ b/src/pages/steps/common.tsx
@@ -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>
+}
diff --git a/src/pages/steps/insurance.tsx b/src/pages/steps/insurance.tsx
new file mode 100644
index 0000000..2245c53
--- /dev/null
+++ b/src/pages/steps/insurance.tsx
@@ -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>
+}
diff --git a/src/pages/steps/plan.tsx b/src/pages/steps/plan.tsx
index 197c0cb..7a94c7f 100644
--- a/src/pages/steps/plan.tsx
+++ b/src/pages/steps/plan.tsx
@@ -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, FileFind } 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 = () => {
@@ -18,20 +18,22 @@ const PlanActions = () => {
     const { t } = useTranslation();
 
     const ReviewAction = (props: ButtonProps) =>
-        <Button startIcon={ <FileFind/> } { ...props }>{ t('review') }</Button>
+        <Button startIcon={ <FileDownloadOutline /> } color="primary" { ...props }>{ t('steps.plan.download') }</Button>
 
     const FormAction = ({ children = t('steps.plan.form'), ...props }: ButtonProps) =>
-        <Button to={ route("plan") } variant="contained" color="primary" component={ RouterLink } { ...props as any }>
-            { children }
+        <Button to={ route("internship_plan") } variant="contained" color="primary" component={ RouterLink } startIcon={ <FileUploadOutline /> }>
+            { t('steps.plan.submit') }
         </Button>
 
-    const ContactAction = (props: ButtonProps) =>
-        <Button startIcon={ <CommentQuestion/> } variant="outlined" color="primary" { ...props }>{ t('contact') }</Button>
+    const TemplateAction = (props: ButtonProps) =>
+        <Button href="https://eti.pg.edu.pl/documents/611675/100028367/indywidualny%20program%20praktyk" startIcon={ <DescriptionIcon/> } { ...props }>
+            { t('steps.plan.template') }
+        </Button>
 
     switch (status) {
         case "awaiting":
             return <Actions>
-                <ReviewAction/>
+                <ReviewAction />
             </Actions>
         case "accepted":
             return <Actions>
@@ -41,16 +43,14 @@ const PlanActions = () => {
         case "declined":
             return <Actions>
                 <FormAction>{ t('fix-errors') }</FormAction>
+                <ReviewAction />
+                <TemplateAction />
                 <ContactAction/>
             </Actions>
         case "draft":
             return <Actions>
-                <Button to={ route("internship_plan") } variant="contained" color="primary" component={ RouterLink }>
-                    { t('steps.plan.submit') }
-                </Button>
-                <Button href="https://eti.pg.edu.pl/documents/611675/100028367/indywidualny%20program%20praktyk" startIcon={ <DescriptionIcon/> }>
-                    { t('steps.plan.template') }
-                </Button>
+                <FormAction />
+                <TemplateAction />
             </Actions>
 
         default:
diff --git a/src/pages/steps/proposal.tsx b/src/pages/steps/proposal.tsx
index 5565cdc..f7646d9 100644
--- a/src/pages/steps/proposal.tsx
+++ b/src/pages/steps/proposal.tsx
@@ -10,15 +10,19 @@ 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));
     const { t } = useTranslation();
 
     const ReviewAction = (props: ButtonProps) =>
-        <Button startIcon={ <FileFind/> } { ...props }>{ t('review') }</Button>
+        <Button startIcon={ <FileFind/> }
+                component={ RouterLink } to={ route("internship_proposal_preview") }
+                { ...props as any }>
+            { t('review') }
+        </Button>
 
     const FormAction = ({ children = t('steps.internship-proposal.form'), ...props }: ButtonProps) =>
         <Button to={ route("internship_proposal") } variant="contained" color="primary" component={ RouterLink }
@@ -26,9 +30,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 +43,7 @@ const ProposalActions = () => {
         case "declined":
             return <Actions>
                 <FormAction>{ t('fix-errors') }</FormAction>
-                <ContactAction/>
+                <ContactAction />
             </Actions>
         case "draft":
             return <Actions>
diff --git a/src/routing.tsx b/src/routing.tsx
index adb533a..c0e3e2e 100644
--- a/src/routing.tsx
+++ b/src/routing.tsx
@@ -1,7 +1,7 @@
 import React, { ReactComponentElement } from "react";
 import { MainPage } from "@/pages/main";
 import { RouteProps } from "react-router-dom";
-import { InternshipProposalPage } from "@/pages/internship/proposal";
+import { InternshipProposalFormPage, InternshipProposalPreviewPage } from "@/pages/internship/proposal";
 import { NotFoundPage } from "@/pages/errors/not-found";
 import SubmitPlanPage from "@/pages/internship/plan";
 
@@ -13,7 +13,8 @@ type Route = {
 export const routes: Route[] = [
     { name: "home", path: "/", exact: true, content: () => <MainPage/> },
 
-    { name: "internship_proposal", path: "/internship/proposal", exact: true, content: () => <InternshipProposalPage/> },
+    { name: "internship_proposal", path: "/internship/proposal", exact: true, content: () => <InternshipProposalFormPage/> },
+    { name: "internship_proposal_preview", path: "/internship/preview/proposal", exact: true, content: () => <InternshipProposalPreviewPage/> },
     { name: "internship_plan", path: "/internship/plan", exact: true, content: () => <SubmitPlanPage/> },
 
     // fallback route for 404 pages
diff --git a/src/serialization/internship.ts b/src/serialization/internship.ts
index be27ddf..9a9f628 100644
--- a/src/serialization/internship.ts
+++ b/src/serialization/internship.ts
@@ -1,6 +1,7 @@
 import { Internship, InternshipType } from "@/data";
 import { Serializable, SerializationTransformer } from "@/serialization/types";
 import { momentSerializationTransformer } from "@/serialization/moment";
+import { Moment } from "moment";
 
 export const internshipSerializationTransformer: SerializationTransformer<Internship> = {
     transform: (internship: Internship): Serializable<Internship> => ({
@@ -10,8 +11,8 @@ export const internshipSerializationTransformer: SerializationTransformer<Intern
     }),
     reverseTransform: (serialized: Serializable<Internship>): Internship => ({
         ...serialized,
-        startDate: momentSerializationTransformer.reverseTransform(serialized.startDate),
-        endDate: momentSerializationTransformer.reverseTransform(serialized.endDate),
+        startDate: momentSerializationTransformer.reverseTransform(serialized.startDate) as Moment,
+        endDate: momentSerializationTransformer.reverseTransform(serialized.endDate) as Moment,
         type: serialized.type as InternshipType,
     }),
 }
diff --git a/src/state/actions/index.ts b/src/state/actions/index.ts
index f5bcdfb..54ac996 100644
--- a/src/state/actions/index.ts
+++ b/src/state/actions/index.ts
@@ -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>>()
diff --git a/src/state/actions/insurance.ts b/src/state/actions/insurance.ts
new file mode 100644
index 0000000..721d7d6
--- /dev/null
+++ b/src/state/actions/insurance.ts
@@ -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;
diff --git a/src/state/reducer/index.ts b/src/state/reducer/index.ts
index 3d139e2..ca5d238 100644
--- a/src/state/reducer/index.ts
+++ b/src/state/reducer/index.ts
@@ -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>;
diff --git a/src/state/reducer/insurance.ts b/src/state/reducer/insurance.ts
new file mode 100644
index 0000000..d5aaa4f
--- /dev/null
+++ b/src/state/reducer/insurance.ts
@@ -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;
+    }
+}
diff --git a/src/styles/index.ts b/src/styles/index.ts
new file mode 100644
index 0000000..c7b6bdf
--- /dev/null
+++ b/src/styles/index.ts
@@ -0,0 +1 @@
+export * from "./spacing"
diff --git a/src/styles/page.scss b/src/styles/page.scss
index 8b41597..f6a1b68 100644
--- a/src/styles/page.scss
+++ b/src/styles/page.scss
@@ -12,3 +12,11 @@
   font-weight: 400;
   line-height: 1.5;
 }
+
+.proposal__primary {
+  font-size: 1.675rem;
+}
+
+.proposal__header:not(:first-child) {
+  margin-top: 1rem;
+}
diff --git a/src/styles/spacing.ts b/src/styles/spacing.ts
new file mode 100644
index 0000000..dc8863d
--- /dev/null
+++ b/src/styles/spacing.ts
@@ -0,0 +1,19 @@
+import { createStyles, makeStyles } from "@material-ui/core/styles";
+
+const defaultSpacing: number = 3;
+
+export const useVerticalSpacing = makeStyles(theme => createStyles({
+    root: {
+        "& > *:not(:last-child)": {
+            marginBottom: (spacing: number = defaultSpacing) => theme.spacing(spacing)
+        }
+    }
+}))
+
+export const useHorizontalSpacing = makeStyles(theme => createStyles({
+    root: {
+        "& > *:not(:last-child)": {
+            marginRight: (spacing: number = defaultSpacing) => theme.spacing(spacing)
+        }
+    }
+}))
diff --git a/src/utils/numbers.ts b/src/utils/numbers.ts
new file mode 100644
index 0000000..090761b
--- /dev/null
+++ b/src/utils/numbers.ts
@@ -0,0 +1,32 @@
+const roman = {
+    M: 1000,
+    CM: 900,
+    D: 500,
+    CD: 400,
+    C: 100,
+    XC: 90,
+    L: 50,
+    XL: 40,
+    X: 10,
+    IX: 9,
+    V: 5,
+    IV: 4,
+    I: 1
+};
+
+type RomanLiteral = keyof typeof roman;
+
+// shamefully stolen from https://stackoverflow.com/questions/9083037/convert-a-number-into-a-roman-numeral-in-javascript
+export function convertToRoman(number: number) {
+    let result = '';
+
+    for (const i in roman) {
+        const q = Math.floor(number / roman[i as RomanLiteral]);
+
+        number -= q * roman[i as RomanLiteral];
+
+        result += i.repeat(q);
+    }
+
+    return result;
+}
diff --git a/translations/pl.yaml b/translations/pl.yaml
index 6c9bfc3..c52c43d 100644
--- a/translations/pl.yaml
+++ b/translations/pl.yaml
@@ -18,6 +18,8 @@ fix-errors: popraw uwagi
 contact: skontaktuj się z pełnomocnikiem
 comments: Zgłoszone uwagi
 send-again: wyślij ponownie
+cancel: anuluj
+
 
 dropzone: "Przeciągnij i upuść plik bądź kliknij, aby wybrać"
 
@@ -26,9 +28,13 @@ sections:
     header: "Moja praktyka"
 
 forms:
+  internship:
+    send-confirmation: >
+      Po wysłaniu zgłoszenia nie będzie możliwości jego zmiany do czasu zweryfikowania go przez pełnomocnika ds. Twojego
+      kierunku. Czy na pewno chcesz wysłać zgłoszenie praktyki w tej formie?
   plan:
     instructions: >
-      Wypełnij i zeskanuj Indywidualny Plan Praktyk a następnie wyślij go z pomocą tego formularza. <więcej informacji>
+      Wypełnij i zeskanuj Indywidualny program Praktyk a następnie wyślij go z pomocą tego formularza. <więcej informacji>
     dropzone-help: Skan dokumentu w formacie PDF
 
 student:
@@ -46,18 +52,37 @@ submission:
     declined: "do poprawy"
     draft: "wersja robocza"
 
+internship:
+  intern:
+    semester: semestr {{ semester, roman }}
+    album: "numer albumu {{ album }}"
+  date-range: "{{ start, DD MMMM YYYY }} - {{ end, DD MMMM YYYY }}"
+  duration: "{{ duration, humanize }}"
+  hours: "{{ hours }} godzin"
+  office: "Oddział / adres"
+  address:
+    city: "{{ city }}, {{ country }}"
+    street: "{{ postalCode }}, {{ street }} {{ building }}"
+  sections:
+    intern-info: "Dane osoby odbywającej praktykę"
+    duration: "Czas trwania praktyki"
+    place: "Miejsce odbywania praktyki"
+    kind: "Rodzaj i program praktyki"
+    mentor: "Zakładowy opiekun praktyki"
+
+
 steps:
   personal-data:
     header: "Uzupełnienie informacji"
     info: >
       Twój profil jest niekompletny. W celu kontynuacji praktyki musisz uzupełnić informacje podane poniżej. Jeżeli masz
-      problem z uzupełnieniem tych informacji - skontaktuj się z koordynatorem praktyk dla Twojego kierunku.
+      problem z uzupełnieniem tych informacji - skontaktuj się z pełnomocnikiem ds. praktyk dla Twojego kierunku.
     form: "Uzupełnij dane"
   internship-proposal:
     header: "Zgłoszenie praktyki"
     info:
       draft: >
-        Przed podjęciem praktyki należy ją zgłosić.
+        Przed podjęciem praktyki należy ją zgłosić. (TODO)
       awaiting: >
         Twoje zgłoszenie musi zostać zweryfikowane i zatwierdzone. Po weryfikacji zostaniesz poinformowany o
         akceptacji bądź konieczności wprowadzenia zmian.
@@ -74,18 +99,23 @@ steps:
       draft: >
         TODO
       awaiting: >
-        TODO
+        Twój indywidualny program praktyki został poprawnie zapisany w systemie. Musi on jeszcze zostać zweryfikowany i
+        zatwierdzony. Po weryfikacji zostaniesz poinformowany o akceptacji bądź konieczności wprowadzenia zmian.
       accepted: >
-        TODO
+        Twój indywidualny program praktyki został zweryfikowany i zaakceptowany.
       declined: >
-        TODO
+        Twój indywidualny program praktyki został zweryfikowany i odrzucony. Popraw zgłoszone uwagi i wyślij nowy program. W
+        razie pytań możesz również skontaktować się z pełnomocnikiem ds. praktyk Twojego kierunku.
     template: "Pobierz szablon"
-    submit: "Wyślij Indywidualny Plan Praktyki"
+    submit: "Wyślij Indywidualny Program Praktyki"
+    download: Twój indywidualny program praktyki
   report:
     header: "Raport z praktyki"
   grade:
     header: "Ocena z praktyki"
   insurance:
     header: "Ubezpieczenie NNW"
+    instructions: >
+      papierki do podpisania...
 
 contact-coordinator: "Skontaktuj się z koordynatorem"