Add basic ipp submit form
This commit is contained in:
parent
e012d015db
commit
b9b63625f1
@ -32,6 +32,7 @@
|
|||||||
"html-webpack-plugin": "4.0.0-beta.11",
|
"html-webpack-plugin": "4.0.0-beta.11",
|
||||||
"i18next": "^19.6.0",
|
"i18next": "^19.6.0",
|
||||||
"i18next-browser-languagedetector": "^5.0.0",
|
"i18next-browser-languagedetector": "^5.0.0",
|
||||||
|
"material-ui-dropzone": "^3.3.0",
|
||||||
"moment": "^2.26.0",
|
"moment": "^2.26.0",
|
||||||
"node-sass": "^4.14.1",
|
"node-sass": "^4.14.1",
|
||||||
"optimize-css-assets-webpack-plugin": "5.0.3",
|
"optimize-css-assets-webpack-plugin": "5.0.3",
|
||||||
|
14
src/components/actions.tsx
Normal file
14
src/components/actions.tsx
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import React, { HTMLProps } from "react";
|
||||||
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
|
|
||||||
|
export const Actions = (props: HTMLProps<HTMLDivElement>) => {
|
||||||
|
const classes = makeStyles(theme => ({
|
||||||
|
root: {
|
||||||
|
"& > *": {
|
||||||
|
marginRight: theme.spacing(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))();
|
||||||
|
|
||||||
|
return <div className={ classes.root } { ...props }/>
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
export * from "./internship/proposal";
|
export * from "./internship/proposal";
|
||||||
export * from "./errors/not-found"
|
export * from "./errors/not-found"
|
||||||
export * from "./main"
|
export * from "./main"
|
||||||
|
export { Actions } from "@/components/actions";
|
||||||
|
52
src/pages/internship/plan.tsx
Normal file
52
src/pages/internship/plan.tsx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import { Page } from "@/pages/base";
|
||||||
|
import { Button, Container, FormHelperText, Grid, Link, Typography } from "@material-ui/core";
|
||||||
|
import { Link as RouterLink } from "react-router-dom";
|
||||||
|
import { route } from "@/routing";
|
||||||
|
import React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { DropzoneArea } from "material-ui-dropzone";
|
||||||
|
import { Description as DescriptionIcon } from "@material-ui/icons";
|
||||||
|
import { Actions } from "@/components/actions";
|
||||||
|
|
||||||
|
export const SubmitPlanPage = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return <Page title={ t("steps.plan.submit") }>
|
||||||
|
<Page.Header maxWidth="md">
|
||||||
|
<Page.Breadcrumbs>
|
||||||
|
<Link component={ RouterLink } to={ route("home") }>{ t('sections.my-internship.header') }</Link>
|
||||||
|
<Typography color="textPrimary">{ t("steps.plan.submit") }</Typography>
|
||||||
|
</Page.Breadcrumbs>
|
||||||
|
<Page.Title>{ t("steps.plan.submit") }</Page.Title>
|
||||||
|
</Page.Header>
|
||||||
|
<Container maxWidth={ "md" }>
|
||||||
|
<Grid container>
|
||||||
|
<Grid item>
|
||||||
|
<Typography variant="body1" component="p">{ t('forms.plan.instructions') }</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<Button href="https://eti.pg.edu.pl/documents/611675/100028367/indywidualny%20program%20praktyk" startIcon={ <DescriptionIcon /> }>
|
||||||
|
{ t('steps.plan.template') }
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<DropzoneArea acceptedFiles={["image/*", "application/x-pdf"]} filesLimit={ 1 } dropzoneText={ t("dropzone") }/>
|
||||||
|
<FormHelperText>{ t('forms.plan.dropzone-help') }</FormHelperText>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<Actions>
|
||||||
|
<Button variant="contained" color="primary">
|
||||||
|
{ t('confirm') }
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button component={ RouterLink } to={ route("home") }>
|
||||||
|
{ t('go-back') }
|
||||||
|
</Button>
|
||||||
|
</Actions>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Container>
|
||||||
|
</Page>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SubmitPlanPage;
|
@ -9,6 +9,8 @@ import { useSelector } from "react-redux";
|
|||||||
import { AppState } from "@/state/reducer";
|
import { AppState } from "@/state/reducer";
|
||||||
import { getMissingStudentData, Student } from "@/data";
|
import { getMissingStudentData, Student } from "@/data";
|
||||||
import { Deadlines, Edition, getEditionDeadlines } from "@/data/edition";
|
import { Deadlines, Edition, getEditionDeadlines } from "@/data/edition";
|
||||||
|
import { Description as DescriptionIcon } from "@material-ui/icons"
|
||||||
|
import { Actions } from "@/components/actions";
|
||||||
|
|
||||||
type StepProps = StepperStepProps & {
|
type StepProps = StepperStepProps & {
|
||||||
until?: Moment;
|
until?: Moment;
|
||||||
@ -57,7 +59,7 @@ export const MainPage = () => {
|
|||||||
<p>{ t('steps.personal-data.info') }</p>
|
<p>{ t('steps.personal-data.info') }</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
{ missingStudentData.map(field => <li key={ field }>{ t(`student.${field}`) }</li>) }
|
{ missingStudentData.map(field => <li key={ field }>{ t(`student.${ field }`) }</li>) }
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<Button to={ route("internship_proposal") } variant="contained" color="primary" component={ RouterLink }>
|
<Button to={ route("internship_proposal") } variant="contained" color="primary" component={ RouterLink }>
|
||||||
@ -75,14 +77,16 @@ export const MainPage = () => {
|
|||||||
<Step label={ t('steps.plan.header') } active={ missingStudentData.length === 0 } until={ deadlines.proposal }>
|
<Step label={ t('steps.plan.header') } active={ missingStudentData.length === 0 } until={ deadlines.proposal }>
|
||||||
<p>{ t('steps.plan.info') }</p>
|
<p>{ t('steps.plan.info') }</p>
|
||||||
|
|
||||||
<Button to={ route("internship_proposal") } component={ RouterLink }>
|
<Actions>
|
||||||
{ t('steps.plan.template') }
|
<Button to={ route("internship_plan") } variant="contained" color="primary" component={ RouterLink }>
|
||||||
</Button>
|
{ t('steps.plan.submit') }
|
||||||
<Button to={ route("internship_proposal") } variant="contained" color="primary" component={ RouterLink }>
|
</Button>
|
||||||
{ t('steps.plan.submit') }
|
<Button href="https://eti.pg.edu.pl/documents/611675/100028367/indywidualny%20program%20praktyk" startIcon={ <DescriptionIcon /> }>
|
||||||
</Button>
|
{ t('steps.plan.template') }
|
||||||
|
</Button>
|
||||||
|
</Actions>
|
||||||
</Step>
|
</Step>
|
||||||
<Step label={ t('steps.insurance.header') } />
|
<Step label={ t('steps.insurance.header') }/>
|
||||||
<Step label={ t('steps.report.header') } until={ deadlines.report }/>
|
<Step label={ t('steps.report.header') } until={ deadlines.report }/>
|
||||||
<Step label={ t('steps.grade.header') }/>
|
<Step label={ t('steps.grade.header') }/>
|
||||||
</Stepper>
|
</Stepper>
|
||||||
|
@ -3,6 +3,7 @@ import { MainPage } from "@/pages/main";
|
|||||||
import { RouteProps } from "react-router-dom";
|
import { RouteProps } from "react-router-dom";
|
||||||
import { InternshipProposalPage } from "@/pages/internship/proposal";
|
import { InternshipProposalPage } from "@/pages/internship/proposal";
|
||||||
import { NotFoundPage } from "@/pages/errors/not-found";
|
import { NotFoundPage } from "@/pages/errors/not-found";
|
||||||
|
import SubmitPlanPage from "@/pages/internship/plan";
|
||||||
|
|
||||||
type Route = {
|
type Route = {
|
||||||
name?: string;
|
name?: string;
|
||||||
@ -13,6 +14,7 @@ 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: () => <InternshipProposalPage/> },
|
{ name: "internship_proposal", path: "/internship/proposal", exact: true, content: () => <InternshipProposalPage/> },
|
||||||
|
{ name: "internship_plan", path: "/internship/plan", exact: true, content: () => <SubmitPlanPage/> },
|
||||||
|
|
||||||
// fallback route for 404 pages
|
// fallback route for 404 pages
|
||||||
{ name: "fallback", path: "*", content: () => <NotFoundPage/> }
|
{ name: "fallback", path: "*", content: () => <NotFoundPage/> }
|
||||||
|
@ -7,6 +7,8 @@ until: until {{ date }}
|
|||||||
late: late by {{ by }}
|
late: late by {{ by }}
|
||||||
left: '{{ left }} left'
|
left: '{{ left }} left'
|
||||||
|
|
||||||
|
dropzone: "Drag and drop a file here or click to choose"
|
||||||
|
|
||||||
student:
|
student:
|
||||||
name: first name
|
name: first name
|
||||||
surname: last name
|
surname: last name
|
||||||
|
@ -7,10 +7,21 @@ until: do {{ date }}
|
|||||||
late: '{{ by }} spóźnienia'
|
late: '{{ by }} spóźnienia'
|
||||||
left: jeszcze {{ left }}
|
left: jeszcze {{ left }}
|
||||||
|
|
||||||
|
confirm: zatwierdź
|
||||||
|
go-back: wstecz
|
||||||
|
|
||||||
|
dropzone: "Przeciągnij i upuść plik bądź kliknij, aby wybrać"
|
||||||
|
|
||||||
sections:
|
sections:
|
||||||
my-internship:
|
my-internship:
|
||||||
header: "Moja praktyka"
|
header: "Moja praktyka"
|
||||||
|
|
||||||
|
forms:
|
||||||
|
plan:
|
||||||
|
instructions: >
|
||||||
|
Wypełnij i zeskanuj Indywidualny Plan Praktyk a następnie wyślij go z pomocą tego formularza. <więcej informacji>
|
||||||
|
dropzone-help: Skan dokumentu w formacie PDF
|
||||||
|
|
||||||
student:
|
student:
|
||||||
name: imię
|
name: imię
|
||||||
surname: mazwisko
|
surname: mazwisko
|
||||||
|
30
yarn.lock
30
yarn.lock
@ -1776,6 +1776,11 @@ atob@^2.1.2:
|
|||||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||||
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
|
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
|
||||||
|
|
||||||
|
attr-accept@^2.0.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.1.0.tgz#a231a854385d36ff7a99647bb77b33c8a5175aee"
|
||||||
|
integrity sha512-sLzVM3zCCmmDtDNhI0i96k6PUztkotSOXqE4kDGQt/6iDi5M+H0srjeF+QC6jN581l4X/Zq3Zu/tgcErEssavg==
|
||||||
|
|
||||||
autoprefixer@^9.6.1:
|
autoprefixer@^9.6.1:
|
||||||
version "9.8.0"
|
version "9.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.0.tgz#68e2d2bef7ba4c3a65436f662d0a56a741e56511"
|
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.0.tgz#68e2d2bef7ba4c3a65436f662d0a56a741e56511"
|
||||||
@ -3800,6 +3805,13 @@ file-loader@4.3.0:
|
|||||||
loader-utils "^1.2.3"
|
loader-utils "^1.2.3"
|
||||||
schema-utils "^2.5.0"
|
schema-utils "^2.5.0"
|
||||||
|
|
||||||
|
file-selector@^0.1.12:
|
||||||
|
version "0.1.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.1.12.tgz#fe726547be219a787a9dcc640575a04a032b1fd0"
|
||||||
|
integrity sha512-Kx7RTzxyQipHuiqyZGf+Nz4vY9R1XGxuQl/hLoJwq+J4avk/9wxxgZyHKtbyIPJmbD4A66DWGYfyykWNpcYutQ==
|
||||||
|
dependencies:
|
||||||
|
tslib "^1.9.0"
|
||||||
|
|
||||||
file-uri-to-path@1.0.0:
|
file-uri-to-path@1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
|
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
|
||||||
@ -5491,6 +5503,15 @@ map-visit@^1.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
object-visit "^1.0.0"
|
object-visit "^1.0.0"
|
||||||
|
|
||||||
|
material-ui-dropzone@^3.3.0:
|
||||||
|
version "3.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/material-ui-dropzone/-/material-ui-dropzone-3.3.0.tgz#5adb64e7ad71953eb29c7d0616b0b693904eb412"
|
||||||
|
integrity sha512-PBOj5IiGbLxEgNybO28xo381/qe0tMF55U715xGs8XLoyfjOFIoC29u4UL3+SWPYsaP/JIFwR4JW+h32xHugIg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.4.4"
|
||||||
|
clsx "^1.0.2"
|
||||||
|
react-dropzone "^10.2.1"
|
||||||
|
|
||||||
md5.js@^1.3.4:
|
md5.js@^1.3.4:
|
||||||
version "1.3.5"
|
version "1.3.5"
|
||||||
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
|
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
|
||||||
@ -7360,6 +7381,15 @@ react-dom@^16.13.1:
|
|||||||
prop-types "^15.6.2"
|
prop-types "^15.6.2"
|
||||||
scheduler "^0.19.1"
|
scheduler "^0.19.1"
|
||||||
|
|
||||||
|
react-dropzone@^10.2.1:
|
||||||
|
version "10.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-10.2.2.tgz#67b4db7459589a42c3b891a82eaf9ade7650b815"
|
||||||
|
integrity sha512-U5EKckXVt6IrEyhMMsgmHQiWTGLudhajPPG77KFSvgsMqNEHSyGpqWvOMc5+DhEah/vH4E1n+J5weBNLd5VtyA==
|
||||||
|
dependencies:
|
||||||
|
attr-accept "^2.0.0"
|
||||||
|
file-selector "^0.1.12"
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
|
||||||
react-error-overlay@^6.0.7:
|
react-error-overlay@^6.0.7:
|
||||||
version "6.0.7"
|
version "6.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.7.tgz#1dcfb459ab671d53f660a991513cb2f0a0553108"
|
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.7.tgz#1dcfb459ab671d53f660a991513cb2f0a0553108"
|
||||||
|
Loading…
Reference in New Issue
Block a user