diff --git a/.build/deploy.sh b/.build/deploy.sh index 36f34bb..89c7bba 100755 --- a/.build/deploy.sh +++ b/.build/deploy.sh @@ -2,5 +2,6 @@ BUILD_PATH=$1 DEPLOY_PATH=$2 # copy all dist files to deploy path +rsync -avz $BUILD_PATH/public/* $DEPLOY_PATH rsync -avz $BUILD_PATH/build/* $DEPLOY_PATH diff --git a/src/forms/internship.tsx b/src/forms/internship.tsx index 01b8689..752bf28 100644 --- a/src/forms/internship.tsx +++ b/src/forms/internship.tsx @@ -1,5 +1,18 @@ import React, { HTMLProps, useEffect, useMemo, useState } from "react"; -import { Button, FormControl, FormHelperText, Grid, Input, InputLabel, TextField, Typography } from "@material-ui/core"; +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + FormControl, + FormHelperText, + Grid, + Input, + InputLabel, + TextField, + Typography +} from "@material-ui/core"; import { KeyboardDatePicker as DatePicker } from "@material-ui/pickers"; import { CompanyForm } from "@/forms/company"; import { StudentForm } from "@/forms/student"; @@ -46,30 +59,30 @@ const InternshipProgramForm = ({ internship, onChange }: InternshipFormSectionPr return ( <Grid container> - <Grid item md={4}> + <Grid item md={ 4 }> <Autocomplete renderInput={ props => <TextField { ...props } label="Rodzaj praktyki/umowy" fullWidth/> } getOptionLabel={ (option: InternshipType) => internshipTypeLabels[option].label } - renderOption={ (option: InternshipType) => <InternshipTypeItem type={ option } /> } + renderOption={ (option: InternshipType) => <InternshipTypeItem type={ option }/> } options={ Object.values(InternshipType) as InternshipType[] } disableClearable { ...fieldProps("type", (event, value) => value) as any } /> </Grid> - <Grid item md={8}> - { internship.type === InternshipType.Other && <TextField label={"Inny - Wprowadź"} fullWidth/> } + <Grid item md={ 8 }> + { internship.type === InternshipType.Other && <TextField label={ "Inny - Wprowadź" } fullWidth/> } </Grid> - {/*<Grid item>*/} - {/* <FormGroup>*/} - {/* <FormLabel component="legend" className="subsection-header">Realizowane punkty programu praktyk (minimum 3)</FormLabel>*/} - {/* { course.possibleProgramEntries.map(entry => {*/} - {/* return (*/} - {/* <FormControlLabel label={ entry.description } key={ entry.id }*/} - {/* control={ <Checkbox /> }*/} - {/* />*/} - {/* )*/} - {/* }) }*/} - {/* </FormGroup>*/} - {/*</Grid>*/} + {/*<Grid item>*/ } + {/* <FormGroup>*/ } + {/* <FormLabel component="legend" className="subsection-header">Realizowane punkty programu praktyk (minimum 3)</FormLabel>*/ } + {/* { course.possibleProgramEntries.map(entry => {*/ } + {/* return (*/ } + {/* <FormControlLabel label={ entry.description } key={ entry.id }*/ } + {/* control={ <Checkbox /> }*/ } + {/* />*/ } + {/* )*/ } + {/* }) }*/ } + {/* </FormGroup>*/ } + {/*</Grid>*/ } </Grid> ) } @@ -84,7 +97,7 @@ const InternshipDurationForm = ({ internship, onChange }: InternshipFormSectionP const computedHours = useMemo(() => startDate && endDate && computeWorkingHours(startDate, endDate, workingHours / 5), [startDate, endDate, workingHours]); const hours = useMemo(() => overrideHours !== null ? overrideHours : computedHours || null, [overrideHours, computedHours]); - const weeks = useMemo(() => hours !== null ? Math.floor(hours / 40) : null, [ hours ]); + const weeks = useMemo(() => hours !== null ? Math.floor(hours / 40) : null, [hours]); useEffect(() => onChange({ ...internship, hours }), [hours]) @@ -139,7 +152,10 @@ const InternshipDurationForm = ({ internship, onChange }: InternshipFormSectionP } export const InternshipForm: React.FunctionComponent<InternshipFormProps> = props => { - const initialInternshipState = useSelector<AppState, Nullable<Internship>>(state => getInternshipProposal(state.proposal) || { ...emptyInternship, intern: sampleStudent }); + const initialInternshipState = useSelector<AppState, Nullable<Internship>>(state => getInternshipProposal(state.proposal) || { + ...emptyInternship, + intern: sampleStudent + }); const [internship, setInternship] = useState<Nullable<Internship>>(initialInternshipState) const { t } = useTranslation(); @@ -147,11 +163,23 @@ export const InternshipForm: React.FunctionComponent<InternshipFormProps> = prop const dispatch = useDispatch(); const history = useHistory(); + const [confirmDialogOpen, setConfirmDialogOpen] = useState<boolean>(false); + const handleSubmit = () => { + setConfirmDialogOpen(false); + dispatch({ type: InternshipProposalActions.Send, internship: internship as Internship }); history.push(route("home")) } + const handleSubmitConfirmation = () => { + setConfirmDialogOpen(true); + } + + const handleCancel = () => { + setConfirmDialogOpen(false); + } + return ( <div className="internship-form"> <Typography variant="h3" className="section-header">Dane osoby odbywającej praktykę</Typography> @@ -163,12 +191,22 @@ export const InternshipForm: React.FunctionComponent<InternshipFormProps> = prop <Typography variant="h3" className="section-header">Miejsce odbywania praktyki</Typography> <CompanyForm internship={ internship } onChange={ setInternship }/> <Actions> - <Button variant="contained" color="primary" onClick={ handleSubmit }>{ t("confirm") }</Button> + <Button variant="contained" color="primary" onClick={ handleSubmitConfirmation }>{ t("confirm") }</Button> <Button component={ RouterLink } to={ route("home") }> { t('go-back') } </Button> </Actions> + + <Dialog open={ confirmDialogOpen } onClose={ handleCancel }> + <DialogContent> + <DialogContentText>{ t('forms.internship.send-confirmation') }</DialogContentText> + </DialogContent> + <DialogActions> + <Button onClick={ handleCancel }>{ t('cancel') }</Button> + <Button color="primary" autoFocus onClick={ handleSubmit }>{ t('confirm') }</Button> + </DialogActions> + </Dialog> </div> ) } diff --git a/src/pages/steps/plan.tsx b/src/pages/steps/plan.tsx index 197c0cb..e92169d 100644 --- a/src/pages/steps/plan.tsx +++ b/src/pages/steps/plan.tsx @@ -3,7 +3,7 @@ import { AppState } from "@/state/reducer"; import { getSubmissionStatus, SubmissionState, SubmissionStatus } from "@/state/reducer/submission"; import { useTranslation } from "react-i18next"; import { Box, Button, ButtonProps, StepProps } from "@material-ui/core"; -import { CommentQuestion, FileFind } from "mdi-material-ui/index"; +import { CommentQuestion, FileDownloadOutline, FileUploadOutline } from "mdi-material-ui/index"; import { route } from "@/routing"; import { Link as RouterLink } from "react-router-dom"; import { Actions, Step } from "@/components"; @@ -18,11 +18,16 @@ const PlanActions = () => { const { t } = useTranslation(); const ReviewAction = (props: ButtonProps) => - <Button startIcon={ <FileFind/> } { ...props }>{ t('review') }</Button> + <Button startIcon={ <FileDownloadOutline /> } color="primary" { ...props }>{ t('steps.plan.download') }</Button> const FormAction = ({ children = t('steps.plan.form'), ...props }: ButtonProps) => - <Button to={ route("plan") } variant="contained" color="primary" component={ RouterLink } { ...props as any }> - { children } + <Button to={ route("internship_plan") } variant="contained" color="primary" component={ RouterLink } startIcon={ <FileUploadOutline /> }> + { t('steps.plan.submit') } + </Button> + + const TemplateAction = (props: ButtonProps) => + <Button href="https://eti.pg.edu.pl/documents/611675/100028367/indywidualny%20program%20praktyk" startIcon={ <DescriptionIcon/> } { ...props }> + { t('steps.plan.template') } </Button> const ContactAction = (props: ButtonProps) => @@ -31,7 +36,7 @@ const PlanActions = () => { switch (status) { case "awaiting": return <Actions> - <ReviewAction/> + <ReviewAction /> </Actions> case "accepted": return <Actions> @@ -41,16 +46,14 @@ const PlanActions = () => { case "declined": return <Actions> <FormAction>{ t('fix-errors') }</FormAction> + <ReviewAction /> + <TemplateAction /> <ContactAction/> </Actions> case "draft": return <Actions> - <Button to={ route("internship_plan") } variant="contained" color="primary" component={ RouterLink }> - { t('steps.plan.submit') } - </Button> - <Button href="https://eti.pg.edu.pl/documents/611675/100028367/indywidualny%20program%20praktyk" startIcon={ <DescriptionIcon/> }> - { t('steps.plan.template') } - </Button> + <FormAction /> + <TemplateAction /> </Actions> default: diff --git a/translations/pl.yaml b/translations/pl.yaml index 6c9bfc3..07be4d1 100644 --- a/translations/pl.yaml +++ b/translations/pl.yaml @@ -18,6 +18,7 @@ fix-errors: popraw uwagi contact: skontaktuj się z pełnomocnikiem comments: Zgłoszone uwagi send-again: wyślij ponownie +cancel: anuluj dropzone: "Przeciągnij i upuść plik bądź kliknij, aby wybrać" @@ -26,9 +27,13 @@ sections: header: "Moja praktyka" forms: - plan: + internship: + send-confirmation: > + Po wysłaniu zgłoszenia nie będzie możliwości jego zmiany do czasu zweryfikowania go przez pełnomocnika ds. Twojego + kierunku. Czy na pewno chcesz wysłać zgłoszenie praktyki w tej formie? + program: instructions: > - Wypełnij i zeskanuj Indywidualny Plan Praktyk a następnie wyślij go z pomocą tego formularza. <więcej informacji> + Wypełnij i zeskanuj Indywidualny program Praktyk a następnie wyślij go z pomocą tego formularza. <więcej informacji> dropzone-help: Skan dokumentu w formacie PDF student: @@ -51,13 +56,13 @@ steps: header: "Uzupełnienie informacji" info: > Twój profil jest niekompletny. W celu kontynuacji praktyki musisz uzupełnić informacje podane poniżej. Jeżeli masz - problem z uzupełnieniem tych informacji - skontaktuj się z koordynatorem praktyk dla Twojego kierunku. + problem z uzupełnieniem tych informacji - skontaktuj się z pełnomocnikiem ds. praktyk dla Twojego kierunku. form: "Uzupełnij dane" internship-proposal: header: "Zgłoszenie praktyki" info: draft: > - Przed podjęciem praktyki należy ją zgłosić. + Przed podjęciem praktyki należy ją zgłosić. (TODO) awaiting: > Twoje zgłoszenie musi zostać zweryfikowane i zatwierdzone. Po weryfikacji zostaniesz poinformowany o akceptacji bądź konieczności wprowadzenia zmian. @@ -74,13 +79,16 @@ steps: draft: > TODO awaiting: > - TODO + Twój indywidualny program praktyki został poprawnie zapisany w systemie. Musi on jeszcze zostać zweryfikowany i + zatwierdzony. Po weryfikacji zostaniesz poinformowany o akceptacji bądź konieczności wprowadzenia zmian. accepted: > - TODO + Twój indywidualny program praktyki został zweryfikowany i zaakceptowany. declined: > - TODO + Twój indywidualny program praktyki został zweryfikowany i odrzucony. Popraw zgłoszone uwagi i wyślij nowy program. W + razie pytań możesz również skontaktować się z pełnomocnikiem ds. praktyk Twojego kierunku. template: "Pobierz szablon" - submit: "Wyślij Indywidualny Plan Praktyki" + submit: "Wyślij Indywidualny Program Praktyki" + download: Twój indywidualny program praktyki report: header: "Raport z praktyki" grade: