Add mentor information to form
This commit is contained in:
parent
48d2983e01
commit
0b67f95dbf
@ -6,7 +6,7 @@
|
|||||||
<meta name="theme-color" content="#000000" />
|
<meta name="theme-color" content="#000000" />
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap&subset=latin,latin-ext" />
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap&subset=latin,latin-ext" />
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||||
<title>React App</title>
|
<title>Zgłoszenie praktyki studenckiej</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
@ -3,4 +3,3 @@ export * from './company'
|
|||||||
export * from './course'
|
export * from './course'
|
||||||
export * from './internship'
|
export * from './internship'
|
||||||
export * from './student'
|
export * from './student'
|
||||||
export { emptyInternship } from "@/provider/dummy/internship";
|
|
||||||
|
@ -2,6 +2,7 @@ import { Moment } from "moment";
|
|||||||
import { Identifiable } from "./common";
|
import { Identifiable } from "./common";
|
||||||
import { countWorkingWeeksInRange } from "@/utils/date";
|
import { countWorkingWeeksInRange } from "@/utils/date";
|
||||||
import { Student } from "@/data/student";
|
import { Student } from "@/data/student";
|
||||||
|
import { Company } from "@/data/company";
|
||||||
|
|
||||||
export enum InternshipType {
|
export enum InternshipType {
|
||||||
FreeInternship = "FreeInternship",
|
FreeInternship = "FreeInternship",
|
||||||
@ -61,4 +62,13 @@ export interface Internship extends Identifiable {
|
|||||||
endDate: Moment;
|
endDate: Moment;
|
||||||
isAccepted: boolean;
|
isAccepted: boolean;
|
||||||
lengthInWeeks: number;
|
lengthInWeeks: number;
|
||||||
|
mentor: Mentor;
|
||||||
|
company: Company;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Mentor {
|
||||||
|
name: string;
|
||||||
|
surname: string;
|
||||||
|
email: string;
|
||||||
|
phone: string | null;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import { Identifiable } from "./common";
|
|||||||
|
|
||||||
export type Semester = number;
|
export type Semester = number;
|
||||||
|
|
||||||
export interface Student extends Identifiable{
|
export interface Student extends Identifiable {
|
||||||
name: string;
|
name: string;
|
||||||
surname: string;
|
surname: string;
|
||||||
email: string;
|
email: string;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { ChangeEvent, HTMLProps, useMemo, useState } from "react";
|
import React, { HTMLProps, useMemo, useState } from "react";
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
Grid,
|
Grid,
|
||||||
@ -17,12 +17,13 @@ import { KeyboardDatePicker as DatePicker } from "@material-ui/pickers";
|
|||||||
import { CompanyForm } from "@/forms/company";
|
import { CompanyForm } from "@/forms/company";
|
||||||
import { StudentForm } from "@/forms/student";
|
import { StudentForm } from "@/forms/student";
|
||||||
import { sampleStudent } from "@/provider/dummy/student";
|
import { sampleStudent } from "@/provider/dummy/student";
|
||||||
import { Company, Course, emptyInternship, Internship, InternshipType, internshipTypeLabels } from "@/data";
|
import { Course, Internship, InternshipType, internshipTypeLabels } from "@/data";
|
||||||
import { Nullable } from "@/helpers";
|
import { Nullable } from "@/helpers";
|
||||||
import moment, { Moment } from "moment";
|
import moment, { Moment } from "moment";
|
||||||
import { computeWorkingHours } from "@/utils/date";
|
import { computeWorkingHours } from "@/utils/date";
|
||||||
import { Autocomplete } from "@material-ui/lab";
|
import { Autocomplete } from "@material-ui/lab";
|
||||||
import { formFieldProps } from "@/forms/helpers";
|
import { formFieldProps } from "@/forms/helpers";
|
||||||
|
import { emptyInternship } from "@/provider/dummy/internship";
|
||||||
|
|
||||||
export type InternshipFormProps = {}
|
export type InternshipFormProps = {}
|
||||||
|
|
||||||
@ -150,7 +151,7 @@ export const InternshipForm: React.FunctionComponent<InternshipFormProps> = prop
|
|||||||
<Typography variant="h5" className="section-header">Czas trwania praktyki</Typography>
|
<Typography variant="h5" className="section-header">Czas trwania praktyki</Typography>
|
||||||
<InternshipDurationForm internship={ internship } onChange={ setInternship }/>
|
<InternshipDurationForm internship={ internship } onChange={ setInternship }/>
|
||||||
<Typography variant="h5" className="section-header">Miejsce odbywania praktyki</Typography>
|
<Typography variant="h5" className="section-header">Miejsce odbywania praktyki</Typography>
|
||||||
<CompanyForm/>
|
<CompanyForm internship={ internship } onChange={ setInternship }/>
|
||||||
<Button variant="contained" color="primary">Wyślij</Button>
|
<Button variant="contained" color="primary">Wyślij</Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
import React, { HTMLProps, useEffect, useMemo, useState } from "react";
|
import React, { HTMLProps, useEffect, useMemo, useState } from "react";
|
||||||
import { BranchOffice, Company, emptyAddress, emptyBranchOffice, emptyCompany, formatAddress } from "@/data";
|
import { BranchOffice, Company, Course, emptyAddress, emptyBranchOffice, emptyCompany, formatAddress, Mentor } from "@/data";
|
||||||
import { sampleCompanies } from "@/provider/dummy";
|
import { sampleCompanies } from "@/provider/dummy";
|
||||||
import { Autocomplete } from "@material-ui/lab";
|
import { Alert, Autocomplete } from "@material-ui/lab";
|
||||||
import { Grid, TextField, Typography } from "@material-ui/core";
|
import { Button, Grid, TextField, Typography } from "@material-ui/core";
|
||||||
import { formFieldProps } from "./helpers";
|
import { BoundProperty, formFieldProps } from "./helpers";
|
||||||
|
import { InternshipFormSectionProps } from "@/forms/Internship";
|
||||||
|
import { sampleCourse } from "@/provider/dummy/student";
|
||||||
|
import { emptyMentor } from "@/provider/dummy/internship";
|
||||||
|
|
||||||
export type CompanyFormProps = {}
|
export type CompanyFormProps = {} & InternshipFormSectionProps;
|
||||||
|
|
||||||
export type BranchOfficeProps = {
|
export type BranchOfficeProps = {
|
||||||
company: Company,
|
company: Company,
|
||||||
@ -95,10 +98,38 @@ export const BranchForm: React.FC<BranchOfficeProps> = ({ company, disabled = fa
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CompanyForm: React.FunctionComponent<CompanyFormProps> = props => {
|
export const MentorForm = ({ mentor, onMentorChange }: BoundProperty<Mentor, 'onMentorChange', 'mentor'>) => {
|
||||||
|
const fieldProps = formFieldProps(mentor, onMentorChange)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Grid container>
|
||||||
|
<Grid item md={6}>
|
||||||
|
<TextField label="Imię" fullWidth { ...fieldProps("name") }/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item md={6}>
|
||||||
|
<TextField label="Nazwisko" value={ mentor.surname } fullWidth { ...fieldProps("surname") }/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item md={8}>
|
||||||
|
<TextField label="E-mail" value={ mentor.email } fullWidth { ...fieldProps("email") }/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item md={4}>
|
||||||
|
<TextField label="Nr telefonu" value={ mentor.phone } fullWidth { ...fieldProps("phone") }/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CompanyForm: React.FunctionComponent<CompanyFormProps> = ({ internship, onChange }) => {
|
||||||
const [company, setCompany] = useState<Company>(emptyCompany);
|
const [company, setCompany] = useState<Company>(emptyCompany);
|
||||||
|
const [mentor, setMentor] = useState<Mentor>(emptyMentor);
|
||||||
|
|
||||||
const canEdit = useMemo(() => !company.id, [company.id]);
|
const canEdit = useMemo(() => !company.id, [company.id]);
|
||||||
|
|
||||||
|
useEffect(() => onChange({ ...internship, mentor }), [ mentor ]);
|
||||||
|
useEffect(() => onChange({ ...internship, company }), [ company ]);
|
||||||
|
|
||||||
const fieldProps = formFieldProps(company, setCompany)
|
const fieldProps = formFieldProps(company, setCompany)
|
||||||
|
|
||||||
const handleCompanyChange = (event: any, value: Company | string | null) => {
|
const handleCompanyChange = (event: any, value: Company | string | null) => {
|
||||||
@ -133,6 +164,8 @@ export const CompanyForm: React.FunctionComponent<CompanyFormProps> = props => {
|
|||||||
{/* <TextField label={ "Url" } fullWidth { ...fieldProps("url") } disabled={ !canEdit }/>*/}
|
{/* <TextField label={ "Url" } fullWidth { ...fieldProps("url") } disabled={ !canEdit }/>*/}
|
||||||
{/*</Grid>*/}
|
{/*</Grid>*/}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Typography variant="subtitle1" className="subsection-header">Zakładowy opiekun praktyki</Typography>
|
||||||
|
<MentorForm mentor={ mentor } onMentorChange={ setMentor }/>
|
||||||
<Typography variant="subtitle1" className="subsection-header">Oddział</Typography>
|
<Typography variant="subtitle1" className="subsection-header">Oddział</Typography>
|
||||||
<BranchForm company={ company }/>
|
<BranchForm company={ company }/>
|
||||||
</>
|
</>
|
||||||
|
@ -2,22 +2,29 @@ import { DOMEvent } from "@/helpers";
|
|||||||
|
|
||||||
type UpdatingEvent = "onBlur" | "onChange" | "onInput";
|
type UpdatingEvent = "onBlur" | "onChange" | "onInput";
|
||||||
type FormFieldHelperOptions<T> = {
|
type FormFieldHelperOptions<T> = {
|
||||||
event: UpdatingEvent
|
event: UpdatingEvent,
|
||||||
|
property: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formFieldProps<T>(subject: T, update: (value: T) => void, options: Partial<FormFieldHelperOptions<T>> = {}) {
|
export function formFieldProps<T>(subject: T, update: (value: T) => void, options: Partial<FormFieldHelperOptions<T>> = {}) {
|
||||||
const {
|
const {
|
||||||
event = "onChange"
|
event = "onChange",
|
||||||
|
property = "value",
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
return <P extends keyof T, TArgs extends any[]>(
|
return <P extends keyof T, TArgs extends any[]>(
|
||||||
field: P,
|
field: P,
|
||||||
extractor: (...args: TArgs) => T[P] = ((event: DOMEvent<HTMLInputElement>) => event.target.value as unknown as T[P]) as any
|
extractor: (...args: TArgs) => T[P] = ((event: DOMEvent<HTMLInputElement>) => event.target.value as unknown as T[P]) as any
|
||||||
) => ({
|
) => ({
|
||||||
value: subject[field],
|
[property]: subject[field],
|
||||||
[event]: (...args: TArgs) => update({
|
[event]: (...args: TArgs) => update({
|
||||||
...subject,
|
...subject,
|
||||||
[field]: extractor(...args),
|
[field]: extractor(...args),
|
||||||
} as T)
|
} as T)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export type BoundProperty<T, TEvent extends string = 'onChange', TProperty extends string = 'value'> =
|
||||||
|
{ [property in TProperty]: T; } &
|
||||||
|
{ [event in TEvent]: (value: T) => void; }
|
||||||
|
@ -4,9 +4,8 @@ import { makeIdSequence } from "./helpers";
|
|||||||
const companySequence = makeIdSequence();
|
const companySequence = makeIdSequence();
|
||||||
const officeSequence = makeIdSequence();
|
const officeSequence = makeIdSequence();
|
||||||
|
|
||||||
export const sampleCompanies: Company[] = [
|
export const sampleCompanies: Company[] = companySequence.assignIds([
|
||||||
{
|
{
|
||||||
id: companySequence(),
|
|
||||||
name: "Intel",
|
name: "Intel",
|
||||||
url: "https://www.intel.com/content/www/us/en/jobs/locations/poland.html",
|
url: "https://www.intel.com/content/www/us/en/jobs/locations/poland.html",
|
||||||
nip: "9570752316",
|
nip: "9570752316",
|
||||||
@ -22,7 +21,6 @@ export const sampleCompanies: Company[] = [
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: companySequence(),
|
|
||||||
name: "IHS Markit",
|
name: "IHS Markit",
|
||||||
url: "http://ihsgdansk.com/",
|
url: "http://ihsgdansk.com/",
|
||||||
nip: "5842068320",
|
nip: "5842068320",
|
||||||
@ -38,12 +36,10 @@ export const sampleCompanies: Company[] = [
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: companySequence(),
|
|
||||||
name: "Asseco Poland",
|
name: "Asseco Poland",
|
||||||
url: "http://pl.asseco.com/",
|
url: "http://pl.asseco.com/",
|
||||||
nip: "5842068320",
|
nip: "5842068320",
|
||||||
offices: [{
|
offices: officeSequence.assignIds([{
|
||||||
id: officeSequence(),
|
|
||||||
address: {
|
address: {
|
||||||
city: "Gdynia",
|
city: "Gdynia",
|
||||||
street: "ul. Podolska",
|
street: "ul. Podolska",
|
||||||
@ -52,7 +48,6 @@ export const sampleCompanies: Company[] = [
|
|||||||
country: "Poland"
|
country: "Poland"
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
id: officeSequence(),
|
|
||||||
address: {
|
address: {
|
||||||
city: "Łódź",
|
city: "Łódź",
|
||||||
street: "al. Marszałka Józefa Piłsudskiego",
|
street: "al. Marszałka Józefa Piłsudskiego",
|
||||||
@ -61,7 +56,6 @@ export const sampleCompanies: Company[] = [
|
|||||||
country: "Poland"
|
country: "Poland"
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
id: officeSequence(),
|
|
||||||
address: {
|
address: {
|
||||||
city: "Wrocław",
|
city: "Wrocław",
|
||||||
street: "Traugutta",
|
street: "Traugutta",
|
||||||
@ -69,6 +63,6 @@ export const sampleCompanies: Company[] = [
|
|||||||
postalCode: "50-449",
|
postalCode: "50-449",
|
||||||
country: "Poland"
|
country: "Poland"
|
||||||
}
|
}
|
||||||
}]
|
}])
|
||||||
}
|
}
|
||||||
]
|
])
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
import { Nullable } from "@/helpers";
|
import { Nullable } from "@/helpers";
|
||||||
import { Internship, InternshipType } from "@/data";
|
import { emptyCompany, Internship, Mentor } from "@/data";
|
||||||
|
|
||||||
|
export const emptyMentor: Mentor = {
|
||||||
|
phone: null,
|
||||||
|
email: "",
|
||||||
|
name: "",
|
||||||
|
surname: ""
|
||||||
|
}
|
||||||
|
|
||||||
export const emptyInternship: Nullable<Internship> = {
|
export const emptyInternship: Nullable<Internship> = {
|
||||||
intern: null,
|
intern: null,
|
||||||
@ -9,4 +16,6 @@ export const emptyInternship: Nullable<Internship> = {
|
|||||||
program: null,
|
program: null,
|
||||||
isAccepted: false,
|
isAccepted: false,
|
||||||
lengthInWeeks: 0,
|
lengthInWeeks: 0,
|
||||||
|
mentor: emptyMentor,
|
||||||
|
company: emptyCompany,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user