diff --git a/src/i18n.ts b/src/i18n.ts index fe8160e..0952bef 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -4,8 +4,9 @@ import I18nextBrowserLanguageDetector from "i18next-browser-languagedetector"; import "moment/locale/pl" 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 MomentUtils from "@date-io/moment"; const resources = { en: { @@ -52,4 +53,10 @@ i18n document.documentElement.lang = 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; diff --git a/src/index.tsx b/src/index.tsx index 6df4691..0909519 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -10,13 +10,7 @@ import { MuiPickersUtilsProvider } from "@material-ui/pickers"; import moment, { Moment } from "moment-timezone"; import { studentTheme } from "@/ui/theme"; import { BrowserRouter } from "react-router-dom"; -import MomentUtils from "@date-io/moment"; - -class LocalizedMomentUtils extends MomentUtils { - getDatePickerHeaderText(date: Moment): string { - return this.format(date, "d MMM yyyy"); - } -} +import { LocalizedMomentUtils } from "@/i18n"; ReactDOM.render( diff --git a/src/management/api/course.ts b/src/management/api/course.ts new file mode 100644 index 0000000..d9afae3 --- /dev/null +++ b/src/management/api/course.ts @@ -0,0 +1,8 @@ +import { Course } from "@/data"; +import { sampleCourse } from "@/provider/dummy"; + +export async function all(): Promise { + return [ + sampleCourse, + ]; +} diff --git a/src/management/api/index.ts b/src/management/api/index.ts index e2390f7..62e75d7 100644 --- a/src/management/api/index.ts +++ b/src/management/api/index.ts @@ -1,11 +1,13 @@ import * as edition from "./edition" import * as page from "./page" import * as type from "./type" +import * as course from "./course" export const api = { edition, page, - type + type, + course, } export default api; diff --git a/src/management/edition/form.tsx b/src/management/edition/form.tsx new file mode 100644 index 0000000..c516a9c --- /dev/null +++ b/src/management/edition/form.tsx @@ -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; +export const initialEditionFormValues: EditionFormValues = { + course: null, + endDate: null, + minimumInternshipHours: 80, + proposalDeadline: null, + reportingEnd: null, + reportingStart: null, + startDate: null +} + +export const editionFormValuesTransformer: Transformer = identityTransformer; + +export const CoursePickerField = ({ field, form, meta, ...props}: FieldProps) => { + const courses = useAsync(useCallback(() => api.course.all(), [])); + const { t } = useTranslation("management"); + + return } + getOptionLabel={ course => course.name } + value={ field.value } + onChange={ field.onChange } + onBlur={ field.onBlur } + /> +} + +export const DatePickerField = ({ field, form, meta, ...props }: FieldProps) => { + const { value, onChange, onBlur } = field; + + return +} + +export const EditionForm = () => { + const { t } = useTranslation("management"); + const spacing = useSpacing(2); + + return
+ { t("edition.fields.basic") } + + + + + + + + + + + + + + + + + { t("edition.fields.deadlines") } + + + + + + + + + + + + + +
+} diff --git a/src/management/edition/manage.tsx b/src/management/edition/manage.tsx index 7ba0a5c..e78f962 100644 --- a/src/management/edition/manage.tsx +++ b/src/management/edition/manage.tsx @@ -68,7 +68,7 @@ export const ManageEditionPage = () => { { t("edition.manage.management") } } route={ route("management:edition_report_form", { edition: edition.id || "" }) }> - { t("management:edition.report-form.title") } + { t("management:edition.report-fields.title") } } route={ route("management:edition_settings", { edition: edition.id || "" }) }> { t("management:edition.settings.title") } diff --git a/src/management/edition/settings.tsx b/src/management/edition/settings.tsx new file mode 100644 index 0000000..bb7dc1f --- /dev/null +++ b/src/management/edition/settings.tsx @@ -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(useCallback(() => api.edition.details(params.edition), [params.edition])) + + const handleSubmit = () => {}; + + return + + + { t(title) } + + { t(title) } + + + + { edition => + +
+ + +
+ } +
+
+
; +} diff --git a/src/management/routing.tsx b/src/management/routing.tsx index 8e35409..ca1d843 100644 --- a/src/management/routing.tsx +++ b/src/management/routing.tsx @@ -7,11 +7,13 @@ import StaticPageManagement from "@/management/page/list"; import { InternshipTypeManagement } from "@/management/type/list"; import { ManageEditionPage } from "@/management/edition/manage"; import { EditionReportFields } from "@/management/edition/report/fields/list"; +import { EditionSettings } from "@/management/edition/settings"; export const managementRoutes: Route[] = ([ { name: "index", path: "/", content: ManagementIndex, exact: true }, { 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: "editions", path: "/editions", content: EditionsManagement }, diff --git a/translations/management.pl.yaml b/translations/management.pl.yaml index 993c35b..ef70f74 100644 --- a/translations/management.pl.yaml +++ b/translations/management.pl.yaml @@ -21,8 +21,20 @@ edition: start: Początek end: Koniec 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: title: "Pola formularza raportu praktyki" + manage: + management: "Zarządzanie edycją" + internships: "Zarządzanie praktykami" + settings: + title: "Konfiguracja edycji" report-field: preview: Podgląd