diff --git a/src/data/company.ts b/src/data/company.ts
index 5e6f2db..c799e1b 100644
--- a/src/data/company.ts
+++ b/src/data/company.ts
@@ -12,10 +12,10 @@ export interface Company extends Identifiable {
     name: string;
     url?: string;
     nip: string;
-    offices: BranchOffice[];
+    offices: Office[];
 }
 
-export interface BranchOffice extends Identifiable {
+export interface Office extends Identifiable {
     address: Address;
 }
 
@@ -34,7 +34,7 @@ export const emptyAddress: Address = {
     building: ""
 }
 
-export const emptyBranchOffice: BranchOffice = {
+export const emptyBranchOffice: Office = {
     address: emptyAddress,
 }
 
diff --git a/src/data/edition.ts b/src/data/edition.ts
index 7fc5438..0de2052 100644
--- a/src/data/edition.ts
+++ b/src/data/edition.ts
@@ -4,6 +4,8 @@ export type Edition = {
     startDate: Moment;
     endDate: Moment;
     proposalDeadline: Moment;
+    minimumInternshipHours: number;
+    maximumInternshipHours?: number;
 }
 
 export type Deadlines = {
diff --git a/src/data/internship.ts b/src/data/internship.ts
index ace8c57..4cd82ea 100644
--- a/src/data/internship.ts
+++ b/src/data/internship.ts
@@ -1,7 +1,7 @@
 import { Moment } from "moment";
 import { Identifiable } from "./common";
 import { Student } from "@/data/student";
-import { BranchOffice, Company } from "@/data/company";
+import { Company, Office } from "@/data/company";
 
 export enum InternshipType {
     FreeInternship = "FreeInternship",
@@ -64,7 +64,7 @@ export interface Internship extends Identifiable {
     hours: number;
     mentor: Mentor;
     company: Company;
-    office: BranchOffice;
+    office: Office;
 }
 
 export interface Plan extends Identifiable {
diff --git a/src/forms/company.tsx b/src/forms/company.tsx
index 4cfd2b8..74fbfdb 100644
--- a/src/forms/company.tsx
+++ b/src/forms/company.tsx
@@ -1,23 +1,13 @@
 import React, { HTMLProps, useMemo } from "react";
-import { BranchOffice, Company, emptyAddress, emptyBranchOffice, emptyCompany, formatAddress, Mentor } from "@/data";
+import { Company, formatAddress, Office } from "@/data";
 import { sampleCompanies } from "@/provider/dummy";
 import { Autocomplete } from "@material-ui/lab";
 import { Grid, TextField, Typography } from "@material-ui/core";
-import { BoundProperty, formFieldProps } from "./helpers";
-import { InternshipFormSectionProps } from "@/forms/internship";
-import { emptyMentor } from "@/provider/dummy/internship";
-import { useProxyState } from "@/hooks";
+import { InternshipFormValues } from "@/forms/internship";
 import { useTranslation } from "react-i18next";
-import { Field } from "formik";
+import { Field, useFormikContext } from "formik";
 import { TextField as TextFieldFormik } from "formik-material-ui"
 
-export type CompanyFormProps = {} & InternshipFormSectionProps;
-
-export type BranchOfficeProps = {
-    disabled?: boolean;
-    offices?: BranchOffice[];
-} & BoundProperty<BranchOffice, "onChange", "value">
-
 export const CompanyItem = ({ company, ...props }: { company: Company } & HTMLProps<any>) => (
     <div className="company-item" { ...props }>
         <div>{ company.name }</div>
@@ -25,43 +15,65 @@ export const CompanyItem = ({ company, ...props }: { company: Company } & HTMLPr
     </div>
 )
 
-export const OfficeItem = ({ office, ...props }: { office: BranchOffice } & HTMLProps<any>) => (
+export const OfficeItem = ({ office, ...props }: { office: Office } & HTMLProps<any>) => (
     <div className="office-item" { ...props }>
         <div>{ office.address.city }</div>
         <Typography variant="caption">{ formatAddress(office.address) }</Typography>
     </div>
 )
 
-export const BranchForm: React.FC<BranchOfficeProps> = ({ value: office, onChange: setOffice, offices = [], disabled = false }) => {
-    const canEdit = useMemo(() => !office.id && !disabled, [office.id, disabled]);
-    const fieldProps = formFieldProps(office.address, address => setOffice({ ...office, address }))
+export const BranchForm: React.FC = () => {
+    const { values, errors, setValues, touched, setFieldTouched } = useFormikContext<InternshipFormValues>();
     const { t } = useTranslation();
 
-    const handleCityChange = (event: any, value: BranchOffice | string | null) => {
+    const disabled = useMemo(() => !values.companyName, [values.companyName]);
+    const offices = useMemo(() => values.company?.offices || [], [values.company]);
+    const canEdit = useMemo(() => !values.office && !disabled, [values.office, disabled]);
+
+    const handleCityChange = (event: any, value: Office | string | null) => {
         if (typeof value === "string") {
-            setOffice({
-                ...emptyBranchOffice,
-                address: {
-                    ...emptyAddress,
-                    city: value,
-                }
-            });
+            setValues({
+                ...values,
+                office: null,
+                city: value,
+            }, true);
         } else if (typeof value === "object" && value !== null) {
-            setOffice(value);
-        } else {
-            setOffice(emptyBranchOffice);
+            const office = value as Office;
+
+            setValues({
+                ...values,
+                office,
+                city: office.address.city,
+                country: office.address.country,
+                street: office.address.street,
+                building: office.address.building,
+                postalCode: office.address.postalCode,
+            }, true)
+        } else { // null
+            setValues({
+                ...values,
+                office: null,
+                city: "",
+                country: "",
+                street: "",
+                building: "",
+                postalCode: "",
+            }, true)
         }
     }
 
     const handleCityInput = (event: any, value: string) => {
-        const base = office.id ? emptyBranchOffice : office;
-        setOffice({
-            ...base,
-            address: {
-                ...base.address,
-                city: value,
-            }
-        })
+        setValues( {
+            ...values,
+            office: null,
+            ...(values.office ? {
+                country: "",
+                street: "",
+                building: "",
+                postalCode: "",
+            } : { }),
+            city: value,
+        }, true);
     }
 
     return (
@@ -72,25 +84,34 @@ export const BranchForm: React.FC<BranchOfficeProps> = ({ value: office, onChang
                                   disabled={ disabled }
                                   getOptionLabel={ office => typeof office == "string" ? office : office.address.city }
                                   renderOption={ office => <OfficeItem office={ office }/> }
-                                  renderInput={ props => <TextField { ...props } label={ t("forms.internship.fields.city") } fullWidth/> }
+                                  renderInput={
+                                      props =>
+                                          <TextField { ...props }
+                                                     label={ t("forms.internship.fields.city") }
+                                                     fullWidth
+                                                     error={ touched.city && !!errors.city }
+                                                     helperText={ touched.city && errors.city }
+                                          />
+                                  }
                                   onChange={ handleCityChange }
                                   onInputChange={ handleCityInput }
-                                  inputValue={ office.address.city }
-                                  value={ office.id ? office : null }
+                                  onBlur={ ev => setFieldTouched("city", true) }
+                                  inputValue={ values.city }
+                                  value={ values.office ? values.office : null }
                                   freeSolo
                     />
                 </Grid>
                 <Grid item md={ 2 }>
-                    <TextField label={ t("forms.internship.fields.postal-code") } fullWidth disabled={ !canEdit } { ...fieldProps("postalCode") }/>
+                    <Field label={ t("forms.internship.fields.postal-code") } name="postalCode" fullWidth disabled={ !canEdit } component={ TextFieldFormik }/>
                 </Grid>
                 <Grid item md={ 3 }>
-                    <TextField label={ t("forms.internship.fields.country") } fullWidth disabled={ !canEdit } { ...fieldProps("country") }/>
+                    <Field label={ t("forms.internship.fields.country") } name="country" fullWidth disabled={ !canEdit } component={ TextFieldFormik }/>
                 </Grid>
                 <Grid item md={ 10 }>
-                    <TextField label={ t("forms.internship.fields.street") } fullWidth disabled={ !canEdit } { ...fieldProps("street") }/>
+                    <Field label={ t("forms.internship.fields.street") } name="street" fullWidth disabled={ !canEdit } component={ TextFieldFormik }/>
                 </Grid>
                 <Grid item md={ 2 }>
-                    <TextField label={ t("forms.internship.fields.building") } fullWidth disabled={ !canEdit } { ...fieldProps("building") }/>
+                    <Field label={ t("forms.internship.fields.building") } name="building" fullWidth disabled={ !canEdit } component={ TextFieldFormik }/>
                 </Grid>
             </Grid>
         </div>
@@ -102,42 +123,50 @@ export const MentorForm = () => {
 
     return (
         <Grid container>
-            <Grid item md={6}>
-                <Field name="mentorFirstName" label={ t("forms.internship.fields.first-name") } fullWidth component={ TextFieldFormik } />
+            <Grid item md={ 6 }>
+                <Field name="mentorFirstName" label={ t("forms.internship.fields.first-name") } fullWidth component={ TextFieldFormik }/>
             </Grid>
-            <Grid item md={6}>
-                <Field name="mentorLastName" label={ t("forms.internship.fields.last-name") } fullWidth component={ TextFieldFormik } />
+            <Grid item md={ 6 }>
+                <Field name="mentorLastName" label={ t("forms.internship.fields.last-name") } fullWidth component={ TextFieldFormik }/>
             </Grid>
-            <Grid item md={8}>
-                <Field name="mentorEmail" label={ t("forms.internship.fields.e-mail") } fullWidth component={ TextFieldFormik } />
+            <Grid item md={ 8 }>
+                <Field name="mentorEmail" label={ t("forms.internship.fields.e-mail") } fullWidth component={ TextFieldFormik }/>
             </Grid>
-            <Grid item md={4}>
-                <Field name="mentorPhone" label={ t("forms.internship.fields.phone") } fullWidth component={ TextFieldFormik } />
+            <Grid item md={ 4 }>
+                <Field name="mentorPhone" label={ t("forms.internship.fields.phone") } fullWidth component={ TextFieldFormik }/>
             </Grid>
         </Grid>
     );
 }
 
-export const CompanyForm: React.FunctionComponent<CompanyFormProps> = ({ internship, onChange }) => {
-    const [company, setCompany] = useProxyState<Company>(internship.company || emptyCompany, company => onChange({ ...internship, company }));
-    const [mentor, setMentor] = useProxyState<Mentor>(internship.mentor || emptyMentor, mentor => onChange({ ...internship, mentor }));
-    const [office, setOffice] = useProxyState<BranchOffice>(internship.office || emptyBranchOffice, office => onChange({ ...internship, office }));
+export const CompanyForm: React.FunctionComponent = () => {
+    const { values, setValues, errors, touched, setFieldTouched } = useFormikContext<InternshipFormValues>();
     const { t } = useTranslation();
 
-    const canEdit = useMemo(() => !company.id, [company.id]);
-
-    const fieldProps = formFieldProps(company, setCompany)
+    const canEdit = useMemo(() => !values.company, [values.company]);
 
     const handleCompanyChange = (event: any, value: Company | string | null) => {
+        setFieldTouched("companyName", true);
+
         if (typeof value === "string") {
-            setCompany({
-                ...emptyCompany,
-                name: value,
-            });
+            setValues({
+                ...values,
+                company: null,
+                companyName: value
+            }, true)
         } else if (typeof value === "object" && value !== null) {
-            setCompany(value);
+            setValues({
+                ...values,
+                company: value as Company,
+                companyName: value.name,
+                companyNip: value.nip,
+            }, true)
         } else {
-            setCompany(emptyCompany);
+            setValues({
+                ...values,
+                company: null,
+                companyName: "",
+            }, true);
         }
     }
 
@@ -146,24 +175,22 @@ export const CompanyForm: React.FunctionComponent<CompanyFormProps> = ({ interns
             <Grid container>
                 <Grid item>
                     <Autocomplete options={ sampleCompanies }
-                                  getOptionLabel={ option => option.name }
+                                  getOptionLabel={ option => typeof option === "string" ? option : option.name }
                                   renderOption={ company => <CompanyItem company={ company }/> }
-                                  renderInput={ props => <TextField { ...props } label={ t("forms.internship.fields.company-name") } fullWidth/> }
-                                  onChange={ handleCompanyChange } value={ company }
+                                  renderInput={ props => <TextField { ...props } label={ t("forms.internship.fields.company-name") } fullWidth
+                                                                    error={ touched.companyName && !!errors.companyName } helperText={ touched.companyName && errors.companyName }/> }
+                                  onChange={ handleCompanyChange } value={ values.company || values.companyName }
                                   freeSolo
                     />
                 </Grid>
                 <Grid item md={ 4 }>
-                    <TextField label={ t("forms.internship.fields.nip") } fullWidth { ...fieldProps("nip") } disabled={ !canEdit }/>
+                    <Field label={ t("forms.internship.fields.nip") } fullWidth name="companyNip" disabled={ !canEdit } component={ TextFieldFormik }/>
                 </Grid>
-                {/*<Grid item md={ 8 }>*/}
-                {/*    <TextField label={ "Url" } fullWidth { ...fieldProps("url") } disabled={ !canEdit }/>*/}
-                {/*</Grid>*/}
             </Grid>
             <Typography variant="subtitle1" className="subsection-header">{ t("internship.mentor") }</Typography>
-            <MentorForm />
+            <MentorForm/>
             <Typography variant="subtitle1" className="subsection-header">{ t("internship.office") }</Typography>
-            <BranchForm value={ office } onChange={ setOffice } offices={ company.offices } />
+            <BranchForm/>
         </>
     )
 }
diff --git a/src/forms/internship.tsx b/src/forms/internship.tsx
index 7b487eb..7f0b103 100644
--- a/src/forms/internship.tsx
+++ b/src/forms/internship.tsx
@@ -1,15 +1,14 @@
-import React, { HTMLProps, useEffect, useMemo, useState } from "react";
+import React, { HTMLProps, useMemo, useState } from "react";
 import { Button, Dialog, DialogActions, DialogContent, DialogContentText, Grid, TextField, Typography } from "@material-ui/core";
 import { KeyboardDatePicker as DatePicker } from "@material-ui/pickers";
 import { CompanyForm } from "@/forms/company";
 import { StudentForm } from "@/forms/student";
 import { sampleStudent } from "@/provider/dummy/student";
-import { BranchOffice, Company, Internship, InternshipType, internshipTypeLabels, Student } from "@/data";
+import { Company, Internship, InternshipType, internshipTypeLabels, Office, Student } from "@/data";
 import { Nullable } from "@/helpers";
 import moment, { Moment } from "moment";
 import { computeWorkingHours } from "@/utils/date";
 import { Autocomplete } from "@material-ui/lab";
-import { formFieldProps } from "@/forms/helpers";
 import { emptyInternship } from "@/provider/dummy/internship";
 import { InternshipProposalActions, useDispatch } from "@/state/actions";
 import { useTranslation } from "react-i18next";
@@ -17,28 +16,26 @@ import { useSelector } from "react-redux";
 import { AppState } from "@/state/reducer";
 import { Link as RouterLink, useHistory } from "react-router-dom";
 import { route } from "@/routing";
-import { useProxyState } from "@/hooks";
 import { getInternshipProposal } from "@/state/reducer/proposal";
 import { Actions } from "@/components";
-import { Form, Formik } from "formik";
+import { Field, Form, Formik, useFormikContext } from "formik";
 import * as Yup from "yup";
+import { Transformer } from "@/serialization";
+import { TextField as TextFieldFormik } from "formik-material-ui"
+import { Edition } from "@/data/edition";
+import { useUpdateEffect } from "@/hooks";
 
-export type InternshipFormProps = {}
-
-export type InternshipFormSectionProps = {
-    internship: Nullable<Internship>,
-    onChange: (internship: Nullable<Internship>) => void,
-}
-
-export type InternshipFormState = {
+export type InternshipFormValues = {
     startDate: Moment | null;
     endDate: Moment | null;
-    hours: number | null;
+    hours: number | "";
+    workingHours: number;
     companyName: string;
     companyNip: string;
     city: string;
     postalCode: string;
     country: string;
+    street: string;
     building: string;
     mentorFirstName: string;
     mentorLastName: string;
@@ -49,19 +46,20 @@ export type InternshipFormState = {
     // relations
     kind: InternshipType | null;
     company: Company | null;
-    office: BranchOffice | null;
-    student: Student | null;
+    office: Office | null;
+    student: Student;
 }
 
-const emptyInternshipValues: InternshipFormState = {
+const emptyInternshipValues: InternshipFormValues = {
     building: "",
     city: "",
     company: null,
     companyName: "",
     companyNip: "",
     country: "",
+    street: "",
     endDate: null,
-    hours: null,
+    hours: "",
     kind: null,
     kindOther: "",
     mentorEmail: "",
@@ -71,7 +69,8 @@ const emptyInternshipValues: InternshipFormState = {
     office: null,
     postalCode: "",
     startDate: null,
-    student: null
+    student: sampleStudent,
+    workingHours: 40,
 }
 
 export const InternshipTypeItem = ({ type, ...props }: { type: InternshipType } & HTMLProps<any>) => {
@@ -85,89 +84,94 @@ export const InternshipTypeItem = ({ type, ...props }: { type: InternshipType }
     )
 }
 
-const InternshipProgramForm = ({ internship, onChange }: InternshipFormSectionProps) => {
-    const fieldProps = formFieldProps(internship, onChange);
-
+const InternshipProgramForm = () => {
     const { t } = useTranslation();
+    const { values, handleBlur, setFieldValue, errors } = useFormikContext<InternshipFormValues>();
 
     return (
         <Grid container>
             <Grid item md={ 4 }>
-                <Autocomplete renderInput={ props => <TextField { ...props } label={ t("forms.internship.fields.kind") } fullWidth/> }
+                <Autocomplete renderInput={ props => <TextField { ...props } label={ t("forms.internship.fields.kind") } fullWidth error={ !!errors.kind } helperText={ errors.kind }/> }
                               getOptionLabel={ (option: InternshipType) => internshipTypeLabels[option].label }
                               renderOption={ (option: InternshipType) => <InternshipTypeItem type={ option }/> }
                               options={ Object.values(InternshipType) as InternshipType[] }
                               disableClearable
-                              { ...fieldProps("type", (event, value) => value) as any }
+                              value={ values.kind || undefined }
+                              onChange={ (_, value) => setFieldValue("kind", value) }
+                              onBlur={ handleBlur }
                 />
             </Grid>
             <Grid item md={ 8 }>
-                { internship.type === InternshipType.Other && <TextField label={ t("forms.internship.fields.kind") } fullWidth/> }
+                {
+                    values.kind === InternshipType.Other &&
+                    <Field label={ t("forms.internship.fields.kind-other") } name="kindOther" fullWidth component={ TextFieldFormik } />
+                }
             </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>
     )
 }
 
-const InternshipDurationForm = ({ internship, onChange }: InternshipFormSectionProps) => {
+const InternshipDurationForm = () => {
     const { t } = useTranslation();
-
-    const [startDate, setStartDate] = useProxyState<Moment | null>(internship.startDate, value => onChange({ ...internship, startDate: value }));
-    const [endDate, setEndDate] = useProxyState<Moment | null>(internship.endDate, value => onChange({ ...internship, endDate: value }));
+    const {
+        values: { startDate, endDate, workingHours },
+        errors,
+        touched,
+        setFieldTouched,
+        setFieldValue
+    } = useFormikContext<InternshipFormValues>();
 
     const [overrideHours, setHoursOverride] = useState<number | null>(null)
-    const [workingHours, setWorkingHours] = useState<number>(40)
 
     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 / workingHours) : null, [ hours ]);
 
-    useEffect(() => onChange({ ...internship, hours }), [hours])
+    useUpdateEffect(() => {
+        setFieldTouched("hours", true);
+        setFieldValue("hours", hours, true);
+    }, [ hours ]);
 
     return (
         <Grid container>
             <Grid item md={ 6 }>
-                <DatePicker value={ startDate } onChange={ setStartDate }
+                <DatePicker value={ startDate } onChange={ value => setFieldValue("startDate", value) }
                             format="DD MMMM yyyy"
-                            clearable disableToolbar fullWidth
+                            disableToolbar fullWidth
                             variant="inline" label={ t("forms.internship.fields.start-date") }
                             minDate={ moment() }
                 />
             </Grid>
             <Grid item md={ 6 }>
-                <DatePicker value={ endDate } onChange={ setEndDate }
+                <DatePicker value={ endDate } onChange={ value => setFieldValue("endDate", value) }
                             format="DD MMMM yyyy"
-                            clearable disableToolbar fullWidth
+                            disableToolbar fullWidth
                             variant="inline" label={ t("forms.internship.fields.end-date") }
                             minDate={ startDate || moment() }
                 />
             </Grid>
             <Grid item md={ 4 }>
-                <TextField fullWidth label={ t("forms.internship.fields.working-hours") }
-                           value={ workingHours } onChange={ ev => setWorkingHours(parseInt(ev.target.value) || 0) }
-                           helperText={ t("forms.internship.help.working-hours") }
+                <Field component={ TextFieldFormik }
+                       name="workingHours"
+                       label={ t("forms.internship.fields.working-hours") }
+                       helperText={ t("forms.internship.help.working-hours") }
+                       fullWidth
                 />
             </Grid>
             <Grid item md={ 4 }>
-                <TextField fullWidth label={ t("forms.internship.fields.total-hours") }
-                           value={ hours } onChange={ ev => setHoursOverride(parseInt(ev.target.value) || 0) }
+                <TextField fullWidth
+                           label={ t("forms.internship.fields.total-hours") }
+                           error={ !!errors.hours && touched.hours }
+                           helperText={ touched.hours && errors.hours }
+                           value={ hours || "" }
+                           onChange={ ev => setHoursOverride(parseInt(ev.target.value) || 0) }
                 />
             </Grid>
             <Grid item md={ 4 }>
                 <TextField fullWidth label={ t("forms.internship.fields.weeks") }
-                           value={ weeks } disabled
+                           value={ weeks || "" }
+                           disabled
                            helperText={ t("forms.internship.help.weeks") }
                 />
             </Grid>
@@ -175,36 +179,86 @@ const InternshipDurationForm = ({ internship, onChange }: InternshipFormSectionP
     );
 }
 
-export const InternshipForm: React.FunctionComponent<InternshipFormProps> = props => {
-    const initialInternshipState = useSelector<AppState, Nullable<Internship>>(state => getInternshipProposal(state.proposal) || {
+type InternshipConverterContext = {
+    internship: Internship,
+}
+
+const converter: Transformer<Nullable<Internship>, InternshipFormValues, InternshipConverterContext> = {
+    transform(internship: Nullable<Internship>): InternshipFormValues {
+        return {
+            student: internship.intern as Student,
+            kind: internship.type,
+            kindOther: "",
+            startDate: internship.startDate,
+            endDate: internship.endDate,
+            hours: internship.hours || "",
+            building: internship.office?.address?.building || "",
+            office: internship.office,
+            city: internship.office?.address?.city || "",
+            postalCode: internship.office?.address?.postalCode || "",
+            street: internship.office?.address?.street || "",
+            country: internship.office?.address?.country || "",
+            company: internship.company,
+            companyName: internship.company?.name || "",
+            companyNip: internship.company?.nip || "",
+            mentorEmail: internship.mentor?.email || "",
+            mentorFirstName: internship.mentor?.name || "",
+            mentorLastName: internship.mentor?.surname || "",
+            mentorPhone: internship.mentor?.phone || "",
+            workingHours: 40,
+        }
+    },
+    reverseTransform(form: InternshipFormValues, context: InternshipConverterContext): Nullable<Internship> {
+        return {
+            ...context.internship,
+            startDate: form.startDate as Moment,
+            endDate: form.endDate as Moment,
+            office: form.office || {
+                address: {
+                    street: form.street,
+                    postalCode: form.postalCode,
+                    country: form.country,
+                    city: form.city,
+                    building: form.building,
+                }
+            },
+            mentor: {
+                surname: form.mentorLastName,
+                name: form.mentorFirstName,
+                email: form.mentorEmail,
+                phone: form.mentorPhone,
+            },
+            company: form.company || {
+                name: form.companyName,
+                nip: form.companyNip,
+                offices: [],
+            },
+            hours: form.hours as number,
+            type: form.kind as InternshipType,
+        }
+    }
+}
+
+export const InternshipForm: React.FunctionComponent = () => {
+    const initialInternship = useSelector<AppState, Nullable<Internship>>(state => getInternshipProposal(state.proposal) || {
         ...emptyInternship,
+        office: null,
+        company: null,
+        mentor: null,
         intern: sampleStudent
     });
 
-    const [internship, setInternship] = useState<Nullable<Internship>>(initialInternshipState)
+    const edition = useSelector<AppState, Edition>(state => state.edition as Edition);
+
     const { t } = useTranslation();
 
+
     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);
-    }
-
-    const validationSchema = Yup.object<Partial<InternshipFormState>>({
+    const validationSchema = Yup.object<Partial<InternshipFormValues>>({
         mentorFirstName: Yup.string().required(t("validation.required")),
         mentorLastName: Yup.string().required(t("validation.required")),
         mentorEmail: Yup.string()
@@ -214,39 +268,94 @@ export const InternshipForm: React.FunctionComponent<InternshipFormProps> = prop
             .required(t("validation.required"))
             .matches(/^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*$/, t("validation.phone")),
         hours: Yup.number()
-            .min(40, t("validation.internship.minimum-hours")) // todo: take it from edition
+            .min(edition.minimumInternshipHours, t("validation.internship.minimum-hours", { hours: edition.minimumInternshipHours })),
+        companyName: Yup.string().when("company", {
+            is: null,
+            then: Yup.string().required(t("validation.required"))
+        }),
+        companyNip: Yup.string().when("company", {
+            is: null,
+            then: Yup.string()
+                .required(t("validation.required"))
+        }),
+        street: Yup.string().required(t("validation.required")),
+        country: Yup.string().required(t("validation.required")),
+        city: Yup.string().required(t("validation.required")),
+        postalCode: Yup.string().required(t("validation.required")),
+        building: Yup.string().required(t("validation.required")),
+        kindOther: Yup.string().when("kind", {
+            is: (values: InternshipFormValues) => values?.kind !== InternshipType.Other,
+            then: Yup.string().required(t("validation.required"))
+        })
     })
 
+    const values = converter.transform(initialInternship);
+
+    const handleSubmit = (values: InternshipFormValues) => {
+        setConfirmDialogOpen(false);
+
+        dispatch({
+            type: InternshipProposalActions.Send,
+            internship: converter.reverseTransform(values, {
+                internship: initialInternship as Internship,
+            }) as Internship
+        });
+
+        history.push(route("home"))
+    }
+
+    const InnerForm = () => {
+        const { submitForm, validateForm } = useFormikContext();
+
+        const handleSubmitConfirmation = async () => {
+            const errors = await validateForm();
+
+            if (Object.keys(errors).length == 0) {
+                setConfirmDialogOpen(true);
+            }
+        }
+
+        const handleCancel = () => {
+            setConfirmDialogOpen(false);
+        }
+
+        return <Form>
+            <Typography variant="h3" className="section-header">{ t('internship.sections.intern-info') }</Typography>
+            <StudentForm />
+            <Typography variant="h3" className="section-header">{ t('internship.sections.kind' )}</Typography>
+            <InternshipProgramForm />
+            <Typography variant="h3" className="section-header">{ t('internship.sections.duration') }</Typography>
+            <InternshipDurationForm />
+            <Typography variant="h3" className="section-header">{ t('internship.sections.place') }</Typography>
+            <CompanyForm />
+            <Actions>
+                <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={ submitForm }>{ t('confirm') }</Button>
+                </DialogActions>
+            </Dialog>
+        </Form>
+    }
+
     return (
-        <Formik initialValues={ emptyInternshipValues } onSubmit={ values => console.log(values) }
-                validationSchema={ validationSchema } validateOnChange={ false } validateOnBlur={ true }>
-            { formik => <Form>
-                <Typography variant="h3" className="section-header">{ t('internship.sections.intern-info') }</Typography>
-                <StudentForm student={ sampleStudent }/>
-                <Typography variant="h3" className="section-header">{ t('internship.sections.kind' )}</Typography>
-                <InternshipProgramForm internship={ internship } onChange={ setInternship }/>
-                <Typography variant="h3" className="section-header">{ t('internship.sections.duration') }</Typography>
-                <InternshipDurationForm internship={ internship } onChange={ setInternship }/>
-                <Typography variant="h3" className="section-header">{ t('internship.sections.place') }</Typography>
-                <CompanyForm internship={ internship } onChange={ setInternship }/>
-                <Actions>
-                    <Button variant="contained" color="primary" onClick={ () => formik.validateForm(formik.values) }>{ 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={ formik.submitForm }>{ t('confirm') }</Button>
-                    </DialogActions>
-                </Dialog>
-            </Form> }
+        <Formik initialValues={ values }
+                onSubmit={ handleSubmit }
+                validationSchema={ validationSchema }
+                validateOnChange={ false }
+                validateOnBlur={ true }
+        >
+            <InnerForm />
         </Formik>
     )
 }
diff --git a/src/forms/student.tsx b/src/forms/student.tsx
index db1ec6e..1c8ee26 100644
--- a/src/forms/student.tsx
+++ b/src/forms/student.tsx
@@ -1,16 +1,15 @@
-import { Course, Student } from "@/data";
+import { Course } from "@/data";
 import { Button, Grid, TextField } from "@material-ui/core";
 import { Alert, Autocomplete } from "@material-ui/lab";
 import React from "react";
 import { sampleCourse } from "@/provider/dummy/student";
 import { useTranslation } from "react-i18next";
+import { useFormikContext } from "formik";
+import { InternshipFormValues } from "@/forms/internship";
 
-type StudentFormProps = {
-    student: Student
-}
-
-export const StudentForm = ({ student }: StudentFormProps) => {
+export const StudentForm = () => {
     const { t } = useTranslation();
+    const { values: { student } } = useFormikContext<InternshipFormValues>();
 
     return <>
         <Grid container>
diff --git a/src/hooks/index.ts b/src/hooks/index.ts
index 283d0e1..9e7f847 100644
--- a/src/hooks/index.ts
+++ b/src/hooks/index.ts
@@ -1 +1,2 @@
 export * from "./useProxyState"
+export * from "./useUpdateEffect"
diff --git a/src/hooks/useUpdateEffect.ts b/src/hooks/useUpdateEffect.ts
new file mode 100644
index 0000000..939b1c0
--- /dev/null
+++ b/src/hooks/useUpdateEffect.ts
@@ -0,0 +1,15 @@
+import { DependencyList, EffectCallback, useEffect, useRef } from "react";
+
+export const useUpdateEffect = (effect: EffectCallback, dependencies: DependencyList) => {
+    const flag = useRef<boolean>(false);
+
+    useEffect(() => {
+        if (flag.current) {
+            effect();
+        } else {
+            flag.current = true;
+        }
+    }, dependencies)
+}
+
+export default useUpdateEffect;
diff --git a/src/provider/dummy/edition.ts b/src/provider/dummy/edition.ts
index 290a3ac..e53bd4e 100644
--- a/src/provider/dummy/edition.ts
+++ b/src/provider/dummy/edition.ts
@@ -4,5 +4,6 @@ import moment from "moment";
 export const sampleEdition: Edition = {
     startDate: moment("2020-07-01"),
     endDate: moment("2020-09-30"),
-    proposalDeadline: moment("2020-07-31")
+    proposalDeadline: moment("2020-07-31"),
+    minimumInternshipHours: 40,
 }
diff --git a/src/serialization/types.ts b/src/serialization/types.ts
index 94e443d..b7528c6 100644
--- a/src/serialization/types.ts
+++ b/src/serialization/types.ts
@@ -10,9 +10,9 @@ type Simplify<T> = string |
     T extends Object ? Serializable<T> : any;
 
 export type Serializable<T> = { [K in keyof T]: Simplify<T[K]> }
-export type Transformer<TFrom, TResult> = {
-    transform(subject: TFrom): TResult;
-    reverseTransform(subject: TResult): TFrom;
+export type Transformer<TFrom, TResult, TContext = never> = {
+    transform(subject: TFrom, context?: TContext): TResult;
+    reverseTransform(subject: TResult, context?: TContext): TFrom;
 }
 
 export type SerializationTransformer<T, TSerialized = Serializable<T>> = Transformer<T, TSerialized>
diff --git a/translations/pl.yaml b/translations/pl.yaml
index 8fc6115..9bc83eb 100644
--- a/translations/pl.yaml
+++ b/translations/pl.yaml
@@ -163,5 +163,7 @@ validation:
   required: "To pole jest wymagane"
   email: "Wprowadź poprawny adres e-mail"
   phone: "Wprowadź poprawny numer telefonu"
+  internship:
+    minimum-hours: "Minimalna liczba godzin wynosi {{ hours }}"
 
 contact-coordinator: "Skontaktuj się z koordynatorem"