Edition form
This commit is contained in:
parent
bb7887cb93
commit
78377a934e
@ -4,8 +4,9 @@ import I18nextBrowserLanguageDetector from "i18next-browser-languagedetector";
|
|||||||
|
|
||||||
import "moment/locale/pl"
|
import "moment/locale/pl"
|
||||||
import "moment/locale/en-gb"
|
import "moment/locale/en-gb"
|
||||||
import moment, { isDuration, isMoment, unitOfTime } from "moment-timezone";
|
import moment, { isDuration, isMoment, Moment, unitOfTime } from "moment-timezone";
|
||||||
import { convertToRoman } from "@/utils/numbers";
|
import { convertToRoman } from "@/utils/numbers";
|
||||||
|
import MomentUtils from "@date-io/moment";
|
||||||
|
|
||||||
const resources = {
|
const resources = {
|
||||||
en: {
|
en: {
|
||||||
@ -52,4 +53,10 @@ i18n
|
|||||||
document.documentElement.lang = i18n.language;
|
document.documentElement.lang = i18n.language;
|
||||||
moment.locale(i18n.language)
|
moment.locale(i18n.language)
|
||||||
|
|
||||||
|
export class LocalizedMomentUtils extends MomentUtils {
|
||||||
|
getDatePickerHeaderText(date: Moment): string {
|
||||||
|
return this.format(date, "d MMM yyyy");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default i18n;
|
export default i18n;
|
||||||
|
@ -10,13 +10,7 @@ import { MuiPickersUtilsProvider } from "@material-ui/pickers";
|
|||||||
import moment, { Moment } from "moment-timezone";
|
import moment, { Moment } from "moment-timezone";
|
||||||
import { studentTheme } from "@/ui/theme";
|
import { studentTheme } from "@/ui/theme";
|
||||||
import { BrowserRouter } from "react-router-dom";
|
import { BrowserRouter } from "react-router-dom";
|
||||||
import MomentUtils from "@date-io/moment";
|
import { LocalizedMomentUtils } from "@/i18n";
|
||||||
|
|
||||||
class LocalizedMomentUtils extends MomentUtils {
|
|
||||||
getDatePickerHeaderText(date: Moment): string {
|
|
||||||
return this.format(date, "d MMM yyyy");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
|
8
src/management/api/course.ts
Normal file
8
src/management/api/course.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { Course } from "@/data";
|
||||||
|
import { sampleCourse } from "@/provider/dummy";
|
||||||
|
|
||||||
|
export async function all(): Promise<Course[]> {
|
||||||
|
return [
|
||||||
|
sampleCourse,
|
||||||
|
];
|
||||||
|
}
|
@ -1,11 +1,13 @@
|
|||||||
import * as edition from "./edition"
|
import * as edition from "./edition"
|
||||||
import * as page from "./page"
|
import * as page from "./page"
|
||||||
import * as type from "./type"
|
import * as type from "./type"
|
||||||
|
import * as course from "./course"
|
||||||
|
|
||||||
export const api = {
|
export const api = {
|
||||||
edition,
|
edition,
|
||||||
page,
|
page,
|
||||||
type
|
type,
|
||||||
|
course,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default api;
|
export default api;
|
||||||
|
94
src/management/edition/form.tsx
Normal file
94
src/management/edition/form.tsx
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import React, { useCallback } from "react";
|
||||||
|
import { Edition } from "@/data/edition";
|
||||||
|
import { Nullable } from "@/helpers";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { FieldProps, useFormikContext, Field } from "formik";
|
||||||
|
import { identityTransformer, Transformer } from "@/serialization";
|
||||||
|
import { Grid, TextField, Typography } from "@material-ui/core";
|
||||||
|
import { useSpacing } from "@/styles";
|
||||||
|
import { Moment } from "moment-timezone";
|
||||||
|
import { KeyboardDatePicker as DatePicker } from "@material-ui/pickers";
|
||||||
|
import { TextField as TextFieldFormik } from "formik-material-ui";
|
||||||
|
import { Course } from "@/data";
|
||||||
|
import { Autocomplete } from "@material-ui/lab";
|
||||||
|
import { useAsync } from "@/hooks";
|
||||||
|
import api from "@/management/api";
|
||||||
|
|
||||||
|
export type EditionFormValues = Nullable<Edition>;
|
||||||
|
export const initialEditionFormValues: EditionFormValues = {
|
||||||
|
course: null,
|
||||||
|
endDate: null,
|
||||||
|
minimumInternshipHours: 80,
|
||||||
|
proposalDeadline: null,
|
||||||
|
reportingEnd: null,
|
||||||
|
reportingStart: null,
|
||||||
|
startDate: null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const editionFormValuesTransformer: Transformer<Edition, EditionFormValues> = identityTransformer;
|
||||||
|
|
||||||
|
export const CoursePickerField = ({ field, form, meta, ...props}: FieldProps<Course>) => {
|
||||||
|
const courses = useAsync(useCallback(() => api.course.all(), []));
|
||||||
|
const { t } = useTranslation("management");
|
||||||
|
|
||||||
|
return <Autocomplete
|
||||||
|
options={ courses.isLoading ? [] : courses.value as Course[] }
|
||||||
|
renderInput={ props => <TextField { ...props } label={ t("edition.field.course") } fullWidth/> }
|
||||||
|
getOptionLabel={ course => course.name }
|
||||||
|
value={ field.value }
|
||||||
|
onChange={ field.onChange }
|
||||||
|
onBlur={ field.onBlur }
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DatePickerField = ({ field, form, meta, ...props }: FieldProps<Moment>) => {
|
||||||
|
const { value, onChange, onBlur } = field;
|
||||||
|
|
||||||
|
return <DatePicker value={ value }
|
||||||
|
onChange={ onChange }
|
||||||
|
onBlur={ onBlur }
|
||||||
|
{ ...props }
|
||||||
|
format="DD.MM.yyyy"
|
||||||
|
disableToolbar fullWidth
|
||||||
|
variant="inline"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const EditionForm = () => {
|
||||||
|
const { t } = useTranslation("management");
|
||||||
|
const spacing = useSpacing(2);
|
||||||
|
|
||||||
|
return <div className={ spacing.vertical }>
|
||||||
|
<Typography variant="subtitle1">{ t("edition.fields.basic") }</Typography>
|
||||||
|
<Grid container>
|
||||||
|
<Grid item xs={ 12 } md={ 6 }>
|
||||||
|
<Field name="startDate" component={ DatePickerField } label={ t("edition.field.start") } />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={ 12 } md={ 6 }>
|
||||||
|
<Field name="endDate" component={ DatePickerField } label={ t("edition.field.end") } />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={ 12 } md={ 6 }>
|
||||||
|
<Field name="course" component={ CoursePickerField } label={ t("edition.field.course") } />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={ 12 } md={ 6 }>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={ 12 } md={ 6 }>
|
||||||
|
<Field name="minimumInternshipHours" component={ TextFieldFormik } label={ t("edition.field.minimumInternshipHours") } />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<Typography variant="subtitle1">{ t("edition.fields.deadlines") }</Typography>
|
||||||
|
<Grid container>
|
||||||
|
<Grid item xs={ 12 } md={ 6 }>
|
||||||
|
<Field name="proposalDeadline" component={ DatePickerField } label={ t("edition.field.proposalDeadline") } />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={ 12 } md={ 6 }>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={ 12 } md={ 6 }>
|
||||||
|
<Field name="reportingStart" component={ DatePickerField } label={ t("edition.field.reportingStart") } />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={ 12 } md={ 6 }>
|
||||||
|
<Field name="reportingEnd" component={ DatePickerField } label={ t("edition.field.reportingEnd") } />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</div>
|
||||||
|
}
|
@ -68,7 +68,7 @@ export const ManageEditionPage = () => {
|
|||||||
<Typography className={ classes.header }>{ t("edition.manage.management") }</Typography>
|
<Typography className={ classes.header }>{ t("edition.manage.management") }</Typography>
|
||||||
<Management.Menu>
|
<Management.Menu>
|
||||||
<ManagementLink icon={ <FormatPageBreak/> } route={ route("management:edition_report_form", { edition: edition.id || "" }) }>
|
<ManagementLink icon={ <FormatPageBreak/> } route={ route("management:edition_report_form", { edition: edition.id || "" }) }>
|
||||||
{ t("management:edition.report-form.title") }
|
{ t("management:edition.report-fields.title") }
|
||||||
</ManagementLink>
|
</ManagementLink>
|
||||||
<ManagementLink icon={ <CogOutline/> } route={ route("management:edition_settings", { edition: edition.id || "" }) }>
|
<ManagementLink icon={ <CogOutline/> } route={ route("management:edition_settings", { edition: edition.id || "" }) }>
|
||||||
{ t("management:edition.settings.title") }
|
{ t("management:edition.settings.title") }
|
||||||
|
45
src/management/edition/settings.tsx
Normal file
45
src/management/edition/settings.tsx
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import React, { useCallback } from "react";
|
||||||
|
import { Page } from "@/pages/base";
|
||||||
|
import { Management } from "@/management/main";
|
||||||
|
import { Container, Dialog, Typography } from "@material-ui/core";
|
||||||
|
import { Async } from "@/components/async";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { useRouteMatch } from "react-router-dom";
|
||||||
|
import { useAsync } from "@/hooks";
|
||||||
|
import { Edition } from "@/data/edition";
|
||||||
|
import api from "@/management/api";
|
||||||
|
import { Form, Formik } from "formik";
|
||||||
|
import { useSpacing } from "@/styles";
|
||||||
|
import { EditionForm } from "@/management/edition/form";
|
||||||
|
|
||||||
|
const title = "edition.settings.title";
|
||||||
|
|
||||||
|
export function EditionSettings() {
|
||||||
|
const { t } = useTranslation("management");
|
||||||
|
const { params } = useRouteMatch();
|
||||||
|
const spacing = useSpacing();
|
||||||
|
|
||||||
|
const edition = useAsync<Edition>(useCallback(() => api.edition.details(params.edition), [params.edition]))
|
||||||
|
|
||||||
|
const handleSubmit = () => {};
|
||||||
|
|
||||||
|
return <Page>
|
||||||
|
<Page.Header maxWidth="md">
|
||||||
|
<Management.Breadcrumbs>
|
||||||
|
<Typography color="textPrimary">{ t(title) }</Typography>
|
||||||
|
</Management.Breadcrumbs>
|
||||||
|
<Page.Title>{ t(title) }</Page.Title>
|
||||||
|
</Page.Header>
|
||||||
|
<Container maxWidth="md">
|
||||||
|
<Async async={ edition }>
|
||||||
|
{ edition =>
|
||||||
|
<Formik initialValues={ edition } onSubmit={ handleSubmit }>
|
||||||
|
<Form className={ spacing.vertical }>
|
||||||
|
<EditionForm />
|
||||||
|
</Form>
|
||||||
|
</Formik>
|
||||||
|
}
|
||||||
|
</Async>
|
||||||
|
</Container>
|
||||||
|
</Page>;
|
||||||
|
}
|
@ -7,11 +7,13 @@ import StaticPageManagement from "@/management/page/list";
|
|||||||
import { InternshipTypeManagement } from "@/management/type/list";
|
import { InternshipTypeManagement } from "@/management/type/list";
|
||||||
import { ManageEditionPage } from "@/management/edition/manage";
|
import { ManageEditionPage } from "@/management/edition/manage";
|
||||||
import { EditionReportFields } from "@/management/edition/report/fields/list";
|
import { EditionReportFields } from "@/management/edition/report/fields/list";
|
||||||
|
import { EditionSettings } from "@/management/edition/settings";
|
||||||
|
|
||||||
export const managementRoutes: Route[] = ([
|
export const managementRoutes: Route[] = ([
|
||||||
{ name: "index", path: "/", content: ManagementIndex, exact: true },
|
{ name: "index", path: "/", content: ManagementIndex, exact: true },
|
||||||
|
|
||||||
{ name: "edition_report_form", path: "/editions/:edition/report", content: EditionReportFields },
|
{ name: "edition_report_form", path: "/editions/:edition/report", content: EditionReportFields },
|
||||||
|
{ name: "edition_settings", path: "/editions/:edition/settings", content: EditionSettings },
|
||||||
{ name: "edition_manage", path: "/editions/:edition", content: ManageEditionPage },
|
{ name: "edition_manage", path: "/editions/:edition", content: ManageEditionPage },
|
||||||
{ name: "editions", path: "/editions", content: EditionsManagement },
|
{ name: "editions", path: "/editions", content: EditionsManagement },
|
||||||
|
|
||||||
|
@ -21,8 +21,20 @@ edition:
|
|||||||
start: Początek
|
start: Początek
|
||||||
end: Koniec
|
end: Koniec
|
||||||
course: Kierunek
|
course: Kierunek
|
||||||
|
reportingStart: Początek raportowania
|
||||||
|
reportingEnd: Koniec raportowania
|
||||||
|
proposalDeadline: Termin zgłaszania praktyk
|
||||||
|
minimumInternshipHours: Minimalna liczba godzin
|
||||||
|
fields:
|
||||||
|
basic: "Podstawowe"
|
||||||
|
deadlines: "Terminy"
|
||||||
report-fields:
|
report-fields:
|
||||||
title: "Pola formularza raportu praktyki"
|
title: "Pola formularza raportu praktyki"
|
||||||
|
manage:
|
||||||
|
management: "Zarządzanie edycją"
|
||||||
|
internships: "Zarządzanie praktykami"
|
||||||
|
settings:
|
||||||
|
title: "Konfiguracja edycji"
|
||||||
|
|
||||||
report-field:
|
report-field:
|
||||||
preview: Podgląd
|
preview: Podgląd
|
||||||
|
Loading…
Reference in New Issue
Block a user