Add more steps
This commit is contained in:
parent
16d2ef4315
commit
a3db797a06
@ -7,6 +7,7 @@
|
||||
"@babel/preset-typescript": "^7.10.1",
|
||||
"@date-io/moment": "^1.3.13",
|
||||
"@material-ui/core": "^4.10.1",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "^4.0.0-alpha.55",
|
||||
"@material-ui/pickers": "^3.2.10",
|
||||
"@types/classnames": "^2.2.10",
|
||||
|
@ -12,18 +12,12 @@ import { AppState } from "@/state/reducer";
|
||||
import { StudentAction, StudentActions } from "@/state/actions/student";
|
||||
import { sampleStudent } from "@/provider/dummy/student";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import { StudentState } from "@/state/reducer/student";
|
||||
import { Student } from "@/data";
|
||||
|
||||
import "moment/locale/pl"
|
||||
import '@/styles/overrides.scss'
|
||||
import '@/styles/header.scss'
|
||||
import classNames from "classnames";
|
||||
import { Button } from "@material-ui/core";
|
||||
import { PersistGate } from 'redux-persist/integration/react';
|
||||
|
||||
moment.locale("pl")
|
||||
|
||||
class LocalizedMomentUtils extends MomentUtils {
|
||||
getDatePickerHeaderText(date: Moment): string {
|
||||
return this.format(date, "d MMM yyyy");
|
||||
@ -65,6 +59,7 @@ const LanguageSwitcher = ({ className, ...props }: HTMLProps<HTMLUListElement>)
|
||||
const handleLanguageChange = (language: string) => () => {
|
||||
i18n.changeLanguage(language);
|
||||
document.documentElement.lang = language;
|
||||
moment.locale(language)
|
||||
}
|
||||
|
||||
const isActive = (language: string) => language.toLowerCase() === i18n.language.toLowerCase();
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Moment } from "moment";
|
||||
import { Identifiable } from "./common";
|
||||
import { countWorkingWeeksInRange } from "@/utils/date";
|
||||
import { Student } from "@/data/student";
|
||||
import { Company } from "@/data/company";
|
||||
|
||||
|
@ -2,6 +2,11 @@ import i18n from "i18next";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
import I18nextBrowserLanguageDetector from "i18next-browser-languagedetector";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import "moment/locale/pl"
|
||||
import "moment/locale/en-gb"
|
||||
|
||||
const resources = {
|
||||
en: {
|
||||
translation: require('../translations/en.yaml'),
|
||||
@ -23,5 +28,6 @@ i18n
|
||||
})
|
||||
|
||||
document.documentElement.lang = i18n.language;
|
||||
moment.locale(i18n.language)
|
||||
|
||||
export default i18n;
|
||||
|
22
src/pages/errors/not-found.tsx
Normal file
22
src/pages/errors/not-found.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import { Page } from "@/pages/base";
|
||||
import { Box, Button, Container, Divider, Typography } from "@material-ui/core";
|
||||
import { route } from "@/routing";
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
import React from "react";
|
||||
|
||||
export const NotFoundPage = () => {
|
||||
return <Page title="Strona nie została znaleziona">
|
||||
<Container>
|
||||
<Typography variant="h1">404</Typography>
|
||||
<Typography variant="h2">Strona nie została znaleziona</Typography>
|
||||
|
||||
<Box my={ 4 }>
|
||||
<Divider variant="fullWidth"/>
|
||||
</Box>
|
||||
|
||||
<Button to={ route("home") } color="primary" component={ RouterLink }>strona główna</Button>
|
||||
</Container>
|
||||
</Page>
|
||||
}
|
||||
|
||||
export default NotFoundPage;
|
3
src/pages/index.ts
Normal file
3
src/pages/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from "./internship/proposal";
|
||||
export * from "./errors/not-found"
|
||||
export * from "./main"
|
23
src/pages/internship/proposal.tsx
Normal file
23
src/pages/internship/proposal.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import { Page } from "@/pages/base";
|
||||
import { Container, Link, Typography } from "@material-ui/core";
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
import { route } from "@/routing";
|
||||
import { InternshipForm } from "@/forms/Internship";
|
||||
import React from "react";
|
||||
|
||||
export const InternshipProposalPage = () => {
|
||||
return <Page title="Zgłoszenie praktyki">
|
||||
<Page.Header maxWidth="md">
|
||||
<Page.Breadcrumbs>
|
||||
<Link component={ RouterLink } to={ route("home") }>Moja praktyka</Link>
|
||||
<Typography color="textPrimary">Zgłoszenie praktyki</Typography>
|
||||
</Page.Breadcrumbs>
|
||||
<Page.Title>Zgłoszenie praktyki</Page.Title>
|
||||
</Page.Header>
|
||||
<Container maxWidth={ "md" }>
|
||||
<InternshipForm/>
|
||||
</Container>
|
||||
</Page>
|
||||
}
|
||||
|
||||
export default InternshipProposalPage;
|
@ -1,65 +1,58 @@
|
||||
import React from "react";
|
||||
import React, { useMemo } from "react";
|
||||
import { Page } from "@/pages/base";
|
||||
import { Container, Typography, Button, Divider, Box, Stepper, Step, StepLabel, StepContent, Link } from "@material-ui/core";
|
||||
import { InternshipForm } from "@/forms/Internship";
|
||||
import { Box, Button, Container, Step as StepperStep, StepContent, StepLabel, Stepper, StepProps as StepperStepProps, Typography } from "@material-ui/core";
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
import { route } from "@/routing";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import moment, { Moment } from "moment";
|
||||
|
||||
type StepProps = StepperStepProps & {
|
||||
until?: Moment;
|
||||
completedOn?: Moment;
|
||||
label: string;
|
||||
}
|
||||
|
||||
const now = moment();
|
||||
|
||||
const Step = ({ until, label, completedOn, children, completed, ...props }: StepProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const isLate = useMemo(() => until?.isBefore(completedOn || now), [completedOn, until]);
|
||||
const left = useMemo(() => moment.duration(now.diff(until)), [until]);
|
||||
|
||||
return <StepperStep { ...props } completed={ completed || !!completedOn }>
|
||||
<StepLabel>
|
||||
{ label }
|
||||
{ until && <Box>
|
||||
<Typography variant="subtitle2" color="textSecondary">
|
||||
{ t('until', { date: until.format("DD MMMM YYYY") }) }
|
||||
{ isLate && <Typography color="error" display="inline" variant="body2"> - { t('late', { by: moment.duration(now.diff(until)).humanize() }) }</Typography> }
|
||||
{ !isLate && !completed && <Typography display="inline" variant="body2"> - { t('left', { left: left.humanize() }) }</Typography> }
|
||||
</Typography>
|
||||
</Box> }
|
||||
</StepLabel>
|
||||
{ children && <StepContent>{ children }</StepContent> }
|
||||
</StepperStep>
|
||||
}
|
||||
|
||||
export const MainPage = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return <Page my={6}>
|
||||
return <Page my={ 6 }>
|
||||
<Container>
|
||||
<Typography variant="h2">{ t("sections.my-internship.header") }</Typography>
|
||||
<Stepper orientation="vertical" nonLinear>
|
||||
<Step completed active={false}>
|
||||
<StepLabel>
|
||||
{ t('steps.personal-data.header') }
|
||||
<Box>
|
||||
<Typography variant="subtitle2" color="textSecondary">{ t('until', { date: '05.07.2020' }) }</Typography>
|
||||
</Box>
|
||||
</StepLabel>
|
||||
</Step>
|
||||
<Step active>
|
||||
<StepLabel>{ t('steps.internship-proposal.header')}</StepLabel>
|
||||
<StepContent>
|
||||
<Button to={ route("internship_proposal") } variant="contained" color="primary" component={ RouterLink }>
|
||||
{ t('steps.internship-proposal.form') }
|
||||
</Button>
|
||||
</StepContent>
|
||||
<Step label={ t('steps.personal-data.header') } until={ moment("2020-07-01") }/>
|
||||
<Step label={ t('steps.internship-proposal.header') }>
|
||||
<Button to={ route("internship_proposal") } variant="contained" color="primary" component={ RouterLink }>
|
||||
{ t('steps.internship-proposal.form') }
|
||||
</Button>
|
||||
</Step>
|
||||
<Step label={ t('steps.plan.header') } until={ moment("2020-07-22") }/>
|
||||
<Step label={ t('steps.insurance.header') }/>
|
||||
<Step label={ t('steps.report.header') }/>
|
||||
<Step label={ t('steps.grade.header') }/>
|
||||
</Stepper>
|
||||
</Container>
|
||||
</Page>
|
||||
}
|
||||
|
||||
export const InternshipFormPage = () => {
|
||||
return <Page title="Zgłoszenie praktyki">
|
||||
<Page.Header maxWidth="md">
|
||||
<Page.Breadcrumbs>
|
||||
<Link component={ RouterLink } to={ route("home") }>Moja praktyka</Link>
|
||||
<Typography color="textPrimary">Zgłoszenie praktyki</Typography>
|
||||
</Page.Breadcrumbs>
|
||||
<Page.Title>Zgłoszenie praktyki</Page.Title>
|
||||
</Page.Header>
|
||||
<Container maxWidth={"md"}>
|
||||
<InternshipForm />
|
||||
</Container>
|
||||
</Page>
|
||||
}
|
||||
|
||||
export const NotFoundPage = () => {
|
||||
return <Page title="Strona nie została znaleziona">
|
||||
<Container>
|
||||
<Typography variant="h1">404</Typography>
|
||||
<Typography variant="h2">Strona nie została znaleziona</Typography>
|
||||
|
||||
<Box my={ 4 }>
|
||||
<Divider variant="fullWidth" />
|
||||
</Box>
|
||||
|
||||
<Button to={ route("home") } color="primary" component={ RouterLink }>strona główna</Button>
|
||||
</Container>
|
||||
</Page>
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
import React, { ReactComponentElement } from "react";
|
||||
import { InternshipFormPage, MainPage, NotFoundPage } from "@/pages/main";
|
||||
import { MainPage } from "@/pages/main";
|
||||
import { RouteProps } from "react-router-dom";
|
||||
import { InternshipProposalPage } from "@/pages/internship/proposal";
|
||||
import { NotFoundPage } from "@/pages/errors/not-found";
|
||||
|
||||
type Route = {
|
||||
name?: string;
|
||||
@ -8,18 +10,18 @@ type Route = {
|
||||
} & RouteProps;
|
||||
|
||||
export const routes: Route[] = [
|
||||
{ name: "home", path: "/", exact: true, content: () => <MainPage /> },
|
||||
{ name: "home", path: "/", exact: true, content: () => <MainPage/> },
|
||||
|
||||
{ name: "internship_proposal", path: "/internship/proposal", exact: true, content: () => <InternshipFormPage /> },
|
||||
{ name: "internship_proposal", path: "/internship/proposal", exact: true, content: () => <InternshipProposalPage/> },
|
||||
|
||||
// fallback route for 404 pages
|
||||
{ path: "*", content: () => <NotFoundPage /> }
|
||||
{ name: "fallback", path: "*", content: () => <NotFoundPage/> }
|
||||
]
|
||||
|
||||
const routeNameMap = new Map(routes.filter(({name}) => !!name).map(({ name, path }) => [ name, path instanceof Array ? path[0] : path ])) as Map<string, string>
|
||||
const routeNameMap = new Map(routes.filter(({ name }) => !!name).map(({ name, path }) => [name, path instanceof Array ? path[0] : path])) as Map<string, string>
|
||||
|
||||
export function route(name: string, params: { [param: string]: string } = { }) {
|
||||
export function route(name: string, params: { [param: string]: string } = {}) {
|
||||
const url = routeNameMap.get(name) || "";
|
||||
|
||||
return Object.entries(params).reduce((url, [name, value]) => url.replace(`:${name}`, value), url);
|
||||
return Object.entries(params).reduce((url, [name, value]) => url.replace(`:${ name }`, value), url);
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ logout: logout
|
||||
logged-in-as: logged in as <1>{{ name }}</1>
|
||||
|
||||
until: until {{ date }}
|
||||
late: late by {{ by }}
|
||||
left: '{{ left }} left'
|
||||
|
||||
sections:
|
||||
my-internship:
|
||||
@ -11,7 +13,9 @@ sections:
|
||||
|
||||
steps:
|
||||
personal-data:
|
||||
header: "Personal data"
|
||||
header: "Fill personal data"
|
||||
internship-proposal:
|
||||
header: "Internship proposal"
|
||||
form: "Internship proposal form"
|
||||
plan:
|
||||
header: "Individual Internship Plan"
|
||||
|
@ -4,6 +4,8 @@ logout: wyloguj się
|
||||
logged-in-as: zalogowany jako <1>{{ name }}</1>
|
||||
|
||||
until: do {{ date }}
|
||||
late: '{{ by }} spóźnienia'
|
||||
left: jeszcze {{ left }}
|
||||
|
||||
sections:
|
||||
my-internship:
|
||||
@ -15,3 +17,11 @@ steps:
|
||||
internship-proposal:
|
||||
header: "Zgłoszenie praktyki"
|
||||
form: "Formularz zgłaszania praktyki"
|
||||
plan:
|
||||
header: "Indywidualny Program Praktyki"
|
||||
report:
|
||||
header: "Raport z praktyki"
|
||||
grade:
|
||||
header: "Ocena z praktyki"
|
||||
insurance:
|
||||
header: "Ubezpieczenie NWW"
|
||||
|
@ -1043,6 +1043,13 @@
|
||||
react-is "^16.8.0"
|
||||
react-transition-group "^4.4.0"
|
||||
|
||||
"@material-ui/icons@^4.9.1":
|
||||
version "4.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@material-ui/icons/-/icons-4.9.1.tgz#fdeadf8cb3d89208945b33dbc50c7c616d0bd665"
|
||||
integrity sha512-GBitL3oBWO0hzBhvA9KxqcowRUsA0qzwKkURyC8nppnC3fw54KPKZ+d4V1Eeg/UnDRSzDaI9nGCdel/eh9AQMg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.4.4"
|
||||
|
||||
"@material-ui/lab@^4.0.0-alpha.55":
|
||||
version "4.0.0-alpha.55"
|
||||
resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.55.tgz#82a850dc59654e04ee3a31be1b34eb3bf64d5585"
|
||||
|
Loading…
Reference in New Issue
Block a user