feature_validation #10
@ -29,6 +29,7 @@
|
|||||||
"css-loader": "3.4.2",
|
"css-loader": "3.4.2",
|
||||||
"date-holidays": "^1.5.3",
|
"date-holidays": "^1.5.3",
|
||||||
"file-loader": "4.3.0",
|
"file-loader": "4.3.0",
|
||||||
|
"formik": "^2.1.5",
|
||||||
"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",
|
||||||
|
@ -4,5 +4,5 @@ import { useHorizontalSpacing } from "@/styles";
|
|||||||
export const Actions = (props: HTMLProps<HTMLDivElement>) => {
|
export const Actions = (props: HTMLProps<HTMLDivElement>) => {
|
||||||
const classes = useHorizontalSpacing(2);
|
const classes = useHorizontalSpacing(2);
|
||||||
|
|
||||||
return <div className={ classes.root } { ...props }/>
|
return <div className={ classes.root } { ...props } style={{ display: "flex", alignItems: "center" }}/>
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@ export const ProposalPreview = ({ proposal }: ProposalPreviewProps) => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const classes = useVerticalSpacing(3);
|
const classes = useVerticalSpacing(3);
|
||||||
|
|
||||||
const duration = moment.duration(proposal.endDate.diff(proposal.startDate));
|
const duration = moment.duration(proposal.endDate.diff(proposal.startDate));
|
||||||
|
|
||||||
return <div className={ classNames("proposal", classes.root) }>
|
return <div className={ classNames("proposal", classes.root) }>
|
||||||
|
@ -1,9 +1,22 @@
|
|||||||
import { Page } from "@/pages/base";
|
import { Page } from "@/pages/base";
|
||||||
import { Button, Container, Link, Typography } from "@material-ui/core";
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonGroup,
|
||||||
|
Container,
|
||||||
|
Dialog,
|
||||||
|
DialogActions,
|
||||||
|
DialogContent,
|
||||||
|
DialogTitle,
|
||||||
|
Link,
|
||||||
|
Menu,
|
||||||
|
MenuItem,
|
||||||
|
TextField,
|
||||||
|
Typography
|
||||||
|
} from "@material-ui/core";
|
||||||
import { Link as RouterLink, useHistory } from "react-router-dom";
|
import { Link as RouterLink, useHistory } from "react-router-dom";
|
||||||
import { route } from "@/routing";
|
import { route } from "@/routing";
|
||||||
import { InternshipForm } from "@/forms/internship";
|
import { InternshipForm } from "@/forms/internship";
|
||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { ProposalComment } from "@/pages/steps/proposal";
|
import { ProposalComment } from "@/pages/steps/proposal";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { ProposalPreview } from "@/components/proposalPreview";
|
import { ProposalPreview } from "@/components/proposalPreview";
|
||||||
@ -13,7 +26,7 @@ import { AppState } from "@/state/reducer";
|
|||||||
import { internshipSerializationTransformer } from "@/serialization";
|
import { internshipSerializationTransformer } from "@/serialization";
|
||||||
import { Actions } from "@/components";
|
import { Actions } from "@/components";
|
||||||
import { InternshipProposalActions, useDispatch } from "@/state/actions";
|
import { InternshipProposalActions, useDispatch } from "@/state/actions";
|
||||||
import { StickerCheckOutline, StickerRemoveOutline } from "mdi-material-ui/index";
|
import { MenuDown, StickerCheckOutline, StickerRemoveOutline } from "mdi-material-ui/index";
|
||||||
import { useVerticalSpacing } from "@/styles";
|
import { useVerticalSpacing } from "@/styles";
|
||||||
|
|
||||||
export const InternshipProposalFormPage = () => {
|
export const InternshipProposalFormPage = () => {
|
||||||
@ -39,13 +52,49 @@ export const InternshipProposalPreviewPage = () => {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
|
const [isDiscardModalOpen, setDiscardModelOpen] = useState<boolean>(false);
|
||||||
|
const [isAcceptModalOpen, setAcceptModelOpen] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const [comment, setComment] = useState<string>("");
|
||||||
|
const [menuAnchor, setMenuAnchor] = useState<null | HTMLElement>(null);
|
||||||
|
|
||||||
const handleAccept = () => {
|
const handleAccept = () => {
|
||||||
dispatch({ type: InternshipProposalActions.Approve, comment: null });
|
dispatch({ type: InternshipProposalActions.Approve, comment });
|
||||||
history.push(route("home"));
|
history.push(route("home"));
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDiscard = () => {
|
const handleDiscard = () => {
|
||||||
dispatch({ type: InternshipProposalActions.Decline, comment: "Well..." });
|
dispatch({ type: InternshipProposalActions.Decline, comment });
|
||||||
|
history.push(route("home"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAcceptModalClose = () => {
|
||||||
|
setAcceptModelOpen(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDiscardModalClose = () => {
|
||||||
|
setDiscardModelOpen(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDiscardAction = () => {
|
||||||
|
setDiscardModelOpen(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAcceptMenuOpen = (ev: React.MouseEvent<HTMLElement>) => {
|
||||||
|
setMenuAnchor(ev.currentTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAcceptMenuClose = () => {
|
||||||
|
setMenuAnchor(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAcceptWithComment = () => {
|
||||||
|
setAcceptModelOpen(true);
|
||||||
|
setMenuAnchor(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAcceptWithoutComment = () => {
|
||||||
|
dispatch({ type: InternshipProposalActions.Approve, comment: null });
|
||||||
history.push(route("home"));
|
history.push(route("home"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,15 +117,55 @@ export const InternshipProposalPreviewPage = () => {
|
|||||||
{ t('go-back') }
|
{ t('go-back') }
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button onClick={ handleAccept } color="primary" startIcon={ <StickerCheckOutline /> }>
|
<ButtonGroup color="primary" variant="contained">
|
||||||
{ t('accept') }
|
<Button onClick={ handleAcceptWithoutComment } startIcon={ <StickerCheckOutline /> }>
|
||||||
|
{ t('accept-without-comments') }
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button size="small" onClick={ handleAcceptMenuOpen }><MenuDown /></Button>
|
||||||
|
</ButtonGroup>
|
||||||
|
|
||||||
<Button onClick={ handleDiscard } color="secondary" startIcon={ <StickerRemoveOutline /> }>
|
<Menu open={ !!menuAnchor } anchorEl={ menuAnchor } onClose={ handleAcceptMenuClose }>
|
||||||
|
<MenuItem onClick={ handleAcceptWithoutComment }>{ t("accept-without-comments") }</MenuItem>
|
||||||
|
<MenuItem onClick={ handleAcceptWithComment }>{ t("accept-with-comments") }</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
|
||||||
|
<Button onClick={ handleDiscardAction } color="secondary" startIcon={ <StickerRemoveOutline /> }>
|
||||||
{ t('discard') }
|
{ t('discard') }
|
||||||
</Button>
|
</Button>
|
||||||
</Actions>
|
</Actions>
|
||||||
</Container>
|
</Container>
|
||||||
|
<Dialog open={ isDiscardModalOpen } onClose={ handleDiscardModalClose } maxWidth="md">
|
||||||
|
<DialogTitle>{ t("internship.discard.title") }</DialogTitle>
|
||||||
|
<DialogContent className={ classes.root }>
|
||||||
|
<Typography variant="body1">{ t("internship.discard.info") }</Typography>
|
||||||
|
<TextField multiline value={ comment } onChange={ ev => setComment(ev.target.value) } fullWidth label={ t("comments") } rows={3}/>
|
||||||
|
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={ handleDiscardModalClose }>
|
||||||
|
{ t('cancel') }
|
||||||
|
</Button>
|
||||||
|
<Button onClick={ handleDiscard } color="primary" variant="contained">
|
||||||
|
{ t('confirm') }
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
<Dialog open={ isAcceptModalOpen } onClose={ handleAcceptModalClose } maxWidth="md">
|
||||||
|
<DialogTitle>{ t("internship.accept.title") }</DialogTitle>
|
||||||
|
<DialogContent className={ classes.root }>
|
||||||
|
<Typography variant="body1">{ t("internship.accept.info") }</Typography>
|
||||||
|
<TextField multiline value={ comment } onChange={ ev => setComment(ev.target.value) } fullWidth label={ t("comments") }/>
|
||||||
|
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={ handleAcceptModalClose }>
|
||||||
|
{ t('cancel') }
|
||||||
|
</Button>
|
||||||
|
<Button onClick={ handleAccept } color="primary" variant="contained">
|
||||||
|
{ t('confirm') }
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
</Page>
|
</Page>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,9 @@ export const studentTheme = responsiveFontSizes(createMuiTheme({
|
|||||||
},
|
},
|
||||||
MuiContainer: {
|
MuiContainer: {
|
||||||
maxWidth: "md"
|
maxWidth: "md"
|
||||||
|
},
|
||||||
|
MuiTextField: {
|
||||||
|
variant: "outlined"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
palette: {
|
palette: {
|
||||||
|
@ -20,6 +20,10 @@ comments: Zgłoszone uwagi
|
|||||||
send-again: wyślij ponownie
|
send-again: wyślij ponownie
|
||||||
cancel: anuluj
|
cancel: anuluj
|
||||||
|
|
||||||
|
accept: zaakceptuj
|
||||||
|
accept-with-comments: zaakceptuj z uwagami
|
||||||
|
accept-without-comments: zaakceptuj bez uwag
|
||||||
|
discard: zgłoś uwagi
|
||||||
|
|
||||||
dropzone: "Przeciągnij i upuść plik bądź kliknij, aby wybrać"
|
dropzone: "Przeciągnij i upuść plik bądź kliknij, aby wybrać"
|
||||||
|
|
||||||
@ -71,7 +75,12 @@ internship:
|
|||||||
place: "Miejsce odbywania praktyki"
|
place: "Miejsce odbywania praktyki"
|
||||||
kind: "Rodzaj i program praktyki"
|
kind: "Rodzaj i program praktyki"
|
||||||
mentor: "Zakładowy opiekun praktyki"
|
mentor: "Zakładowy opiekun praktyki"
|
||||||
|
discard:
|
||||||
|
title: "Odrzuć zgłoszenie praktyki"
|
||||||
|
info: "Poniższa informacja zostanie przekazana praktykantowi w celu poprawy zgłoszenia."
|
||||||
|
accept:
|
||||||
|
title: "Zaakceptuj zgłoszenie praktyki"
|
||||||
|
info: "Poniższa informacja zostanie przekazana praktykantowi."
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
personal-data:
|
personal-data:
|
||||||
|
37
yarn.lock
37
yarn.lock
@ -3170,6 +3170,11 @@ deep-equal@^1.0.1:
|
|||||||
object-keys "^1.1.1"
|
object-keys "^1.1.1"
|
||||||
regexp.prototype.flags "^1.2.0"
|
regexp.prototype.flags "^1.2.0"
|
||||||
|
|
||||||
|
deepmerge@^2.1.1:
|
||||||
|
version "2.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170"
|
||||||
|
integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==
|
||||||
|
|
||||||
default-gateway@^4.2.0:
|
default-gateway@^4.2.0:
|
||||||
version "4.2.0"
|
version "4.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b"
|
resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b"
|
||||||
@ -3954,6 +3959,20 @@ form-data@~2.3.2:
|
|||||||
combined-stream "^1.0.6"
|
combined-stream "^1.0.6"
|
||||||
mime-types "^2.1.12"
|
mime-types "^2.1.12"
|
||||||
|
|
||||||
|
formik@^2.1.5:
|
||||||
|
version "2.1.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/formik/-/formik-2.1.5.tgz#de5bbbe35543fa6d049fe96b8ee329d6cd6892b8"
|
||||||
|
integrity sha512-bWpo3PiqVDYslvrRjTq0Isrm0mFXHiO33D8MS6t6dWcqSFGeYF52nlpCM2xwOJ6tRVRznDkL+zz/iHPL4LDuvQ==
|
||||||
|
dependencies:
|
||||||
|
deepmerge "^2.1.1"
|
||||||
|
hoist-non-react-statics "^3.3.0"
|
||||||
|
lodash "^4.17.14"
|
||||||
|
lodash-es "^4.17.14"
|
||||||
|
react-fast-compare "^2.0.1"
|
||||||
|
scheduler "^0.18.0"
|
||||||
|
tiny-warning "^1.0.2"
|
||||||
|
tslib "^1.10.0"
|
||||||
|
|
||||||
forwarded@~0.1.2:
|
forwarded@~0.1.2:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
|
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
|
||||||
@ -5364,6 +5383,11 @@ locate-path@^5.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
p-locate "^4.1.0"
|
p-locate "^4.1.0"
|
||||||
|
|
||||||
|
lodash-es@^4.17.14:
|
||||||
|
version "4.17.15"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78"
|
||||||
|
integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ==
|
||||||
|
|
||||||
lodash._reinterpolate@^3.0.0:
|
lodash._reinterpolate@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
|
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
|
||||||
@ -7400,6 +7424,11 @@ react-error-overlay@^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"
|
||||||
integrity sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA==
|
integrity sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA==
|
||||||
|
|
||||||
|
react-fast-compare@^2.0.1:
|
||||||
|
version "2.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
|
||||||
|
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
|
||||||
|
|
||||||
react-i18next@^11.7.0:
|
react-i18next@^11.7.0:
|
||||||
version "11.7.0"
|
version "11.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.7.0.tgz#f27c4c237a274e007a48ac1210db83e33719908b"
|
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.7.0.tgz#f27c4c237a274e007a48ac1210db83e33719908b"
|
||||||
@ -7888,6 +7917,14 @@ sax@~1.2.4:
|
|||||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||||
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
|
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
|
||||||
|
|
||||||
|
scheduler@^0.18.0:
|
||||||
|
version "0.18.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.18.0.tgz#5901ad6659bc1d8f3fdaf36eb7a67b0d6746b1c4"
|
||||||
|
integrity sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==
|
||||||
|
dependencies:
|
||||||
|
loose-envify "^1.1.0"
|
||||||
|
object-assign "^4.1.1"
|
||||||
|
|
||||||
scheduler@^0.19.1:
|
scheduler@^0.19.1:
|
||||||
version "0.19.1"
|
version "0.19.1"
|
||||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196"
|
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196"
|
||||||
|
Loading…
Reference in New Issue
Block a user