diff --git a/src/app.tsx b/src/app.tsx index 97bbf60..009dce1 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -26,7 +26,7 @@ function App() {
Zgłoszenie Praktyki - UX Demo + UX Demo diff --git a/src/data/internship.ts b/src/data/internship.ts index eb6962e..7d0b973 100644 --- a/src/data/internship.ts +++ b/src/data/internship.ts @@ -1,6 +1,7 @@ import { Moment } from "moment"; import { Identifiable } from "./common"; import { countWorkingWeeksInRange } from "@/utils/date"; +import { Student } from "@/data/student"; export enum InternshipType { FreeInternship = "FreeInternship", @@ -14,11 +15,46 @@ export enum InternshipType { Other = "Other", } +export const internshipTypeLabels: { [type in InternshipType]: { label: string, description?: string } } = { + [InternshipType.FreeInternship]: { + label: "Umowa o organizację praktyki", + description: "Praktyka bezpłatna" + }, + [InternshipType.GraduateInternship]: { + label: "Umowa o praktykę absolwencką" + }, + [InternshipType.FreeApprenticeship]: { + label: "Umowa o staż bezpłatny" + }, + [InternshipType.PaidApprenticeship]: { + label: "Umowa o staż płatny", + description: "np. przemysłowy" + }, + [InternshipType.ForeignInternship]: { + label: "Praktyka zagraniczna", + description: "np. IAESTE, ERASMUS" + }, + [InternshipType.UOP]: { + label: "Umowa o pracę" + }, + [InternshipType.UD]: { + label: "Umowa o dzieło (w tym B2B)" + }, + [InternshipType.UZ]: { + label: "Umowa o zlecenie (w tym B2B)" + }, + [InternshipType.Other]: { + label: "Inna", + description: "Należy wprowadzić samodzielnie" + }, +} + export interface InternshipProgramEntry extends Identifiable { description: string; } export interface Internship extends Identifiable { + intern: Student, type: InternshipType; program: InternshipProgramEntry[]; startDate: Moment; diff --git a/src/forms/Internship.tsx b/src/forms/Internship.tsx index 8377236..9292098 100644 --- a/src/forms/Internship.tsx +++ b/src/forms/Internship.tsx @@ -1,21 +1,83 @@ -import React, { ChangeEvent, useMemo, useState } from "react"; -import { FormControl, Grid, Input, InputLabel, Typography, FormHelperText } from "@material-ui/core"; -import { DatePicker } from "@material-ui/pickers"; +import React, { ChangeEvent, HTMLProps, useMemo, useState } from "react"; +import { + FormControl, + Grid, + Input, + InputLabel, + Typography, + FormHelperText, + TextField, + FormGroup, + FormControlLabel, + Checkbox, + FormLabel, + Button +} 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 { emptyInternship, Internship } from "@/data"; +import { Company, Course, emptyInternship, Internship, InternshipType, internshipTypeLabels } 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"; export type InternshipFormProps = {} -export type InternshipDetailsFormProps = { - internship: Nullable +export type InternshipFormSectionProps = { + internship: Nullable, + onChange: (internship: Nullable) => void, } -const InternshipDurationForm = ({ internship }: InternshipDetailsFormProps) => { +export const InternshipTypeItem = ({ type, ...props }: { type: InternshipType } & HTMLProps) => { + const info = internshipTypeLabels[type]; + + return ( +
+
{ info.label }
+ { info.description && { info.description } } +
+ ) +} + +const InternshipProgramForm = ({ internship, onChange }: InternshipFormSectionProps) => { + const fieldProps = formFieldProps(internship, onChange); + + const course = internship.intern?.course as Course; + + return ( + + + } + getOptionLabel={ (option: InternshipType) => internshipTypeLabels[option].label } + renderOption={ (option: InternshipType) => } + options={ Object.values(InternshipType) as InternshipType[] } + disableClearable + { ...fieldProps("type", (event, value) => value) as any } + /> + + + { internship.type === InternshipType.Other && } + + + + Realizowane punkty programu praktyk (minimum 3) + { course.possibleProgramEntries.map(entry => { + return ( + } + /> + ) + }) } + + + + ) +} + +const InternshipDurationForm = ({ internship }: InternshipFormSectionProps) => { const [startDate, setStartDate] = useState(internship.startDate); const [endDate, setEndDate] = useState(internship.endDate); const [overrideHours, setHoursOverride] = useState(null) @@ -28,18 +90,21 @@ const InternshipDurationForm = ({ internship }: InternshipDetailsFormProps) => { return ( - - + + - + - Wymiar etatu @@ -66,6 +131,7 @@ const InternshipDurationForm = ({ internship }: InternshipDetailsFormProps) => { disabled fullWidth /> + Wyliczona automatycznie @@ -73,16 +139,19 @@ const InternshipDurationForm = ({ internship }: InternshipDetailsFormProps) => { } export const InternshipForm: React.FunctionComponent = props => { - const [internship, setInternship] = useState>(emptyInternship) + const [internship, setInternship] = useState>({ ...emptyInternship, intern: sampleStudent }) return (
- Dane osoby odbywającej praktykę + Dane osoby odbywającej praktykę - Czas trwania praktyki - - Miejsce odbywania praktyki + Rodzaj i program praktyki + + Czas trwania praktyki + + Miejsce odbywania praktyki +
) } diff --git a/src/forms/company.tsx b/src/forms/company.tsx index 2f9798a..2319dc2 100644 --- a/src/forms/company.tsx +++ b/src/forms/company.tsx @@ -129,11 +129,11 @@ export const CompanyForm: React.FunctionComponent = props => { - - - + {/**/} + {/* */} + {/**/}
- Oddział + Oddział ) diff --git a/src/forms/helpers.ts b/src/forms/helpers.ts index 13ea3f9..4767e1e 100644 --- a/src/forms/helpers.ts +++ b/src/forms/helpers.ts @@ -10,11 +10,14 @@ export function formFieldProps(subject: T, update: (value: T) => void, option event = "onChange" } = options; - return (field: keyof T) => ({ + return

( + field: P, + extractor: (...args: TArgs) => T[P] = ((event: DOMEvent) => event.target.value as unknown as T[P]) as any + ) => ({ value: subject[field], - [event]: (event: DOMEvent) => update({ + [event]: (...args: TArgs) => update({ ...subject, - [field]: event.target.value, + [field]: extractor(...args), } as T) }) } diff --git a/src/provider/dummy/internship.ts b/src/provider/dummy/internship.ts index e4e2caf..99ab50f 100644 --- a/src/provider/dummy/internship.ts +++ b/src/provider/dummy/internship.ts @@ -1,7 +1,8 @@ import { Nullable } from "@/helpers"; -import { Internship } from "@/data"; +import { Internship, InternshipType } from "@/data"; export const emptyInternship: Nullable = { + intern: null, endDate: null, startDate: null, type: null, diff --git a/src/provider/dummy/student.ts b/src/provider/dummy/student.ts index 3fb0138..1e2387c 100644 --- a/src/provider/dummy/student.ts +++ b/src/provider/dummy/student.ts @@ -35,5 +35,5 @@ export const sampleStudent: Student = { albumNumber: "123456", email: "s123456@student.pg.edu.pl", course: sampleCourse, - semester: 4, + semester: 6, } diff --git a/src/styles/overrides.scss b/src/styles/overrides.scss index d5174f6..e143cac 100644 --- a/src/styles/overrides.scss +++ b/src/styles/overrides.scss @@ -1,3 +1,16 @@ .MuiGrid-container { margin-bottom: 0; + margin-top: 0; +} + +.section-header { + margin-top: 2.5rem; +} + +.subsection-header { + margin-top: 1.5rem; +} + +#root { + margin: 100px 0; }