From 943d83cd268bd0cae29b90ecaced3c5e3098627c Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Wed, 5 Aug 2020 22:17:22 +0200 Subject: [PATCH 1/4] Add IPP descriptions and confirms --- .build/deploy.sh | 1 + src/forms/internship.tsx | 78 +++++++++++++++++++++++++++++----------- src/pages/steps/plan.tsx | 25 +++++++------ translations/pl.yaml | 24 ++++++++----- 4 files changed, 89 insertions(+), 39 deletions(-) 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 ( - + } getOptionLabel={ (option: InternshipType) => internshipTypeLabels[option].label } - renderOption={ (option: InternshipType) => } + renderOption={ (option: InternshipType) => } options={ Object.values(InternshipType) as InternshipType[] } disableClearable { ...fieldProps("type", (event, value) => value) as any } /> - - { internship.type === InternshipType.Other && } + + { internship.type === InternshipType.Other && } - {/**/} - {/* */} - {/* Realizowane punkty programu praktyk (minimum 3)*/} - {/* { course.possibleProgramEntries.map(entry => {*/} - {/* return (*/} - {/* }*/} - {/* />*/} - {/* )*/} - {/* }) }*/} - {/* */} - {/**/} + {/**/ } + {/* */ } + {/* Realizowane punkty programu praktyk (minimum 3)*/ } + {/* { course.possibleProgramEntries.map(entry => {*/ } + {/* return (*/ } + {/* }*/ } + {/* />*/ } + {/* )*/ } + {/* }) }*/ } + {/* */ } + {/**/ } ) } @@ -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 = props => { - const initialInternshipState = useSelector>(state => getInternshipProposal(state.proposal) || { ...emptyInternship, intern: sampleStudent }); + const initialInternshipState = useSelector>(state => getInternshipProposal(state.proposal) || { + ...emptyInternship, + intern: sampleStudent + }); const [internship, setInternship] = useState>(initialInternshipState) const { t } = useTranslation(); @@ -147,11 +163,23 @@ export const InternshipForm: React.FunctionComponent = prop const dispatch = useDispatch(); const history = useHistory(); + const [confirmDialogOpen, setConfirmDialogOpen] = useState(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 (
Dane osoby odbywającej praktykę @@ -163,12 +191,22 @@ export const InternshipForm: React.FunctionComponent = prop Miejsce odbywania praktyki - + + + + + { t('forms.internship.send-confirmation') } + + + + + +
) } 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) => - + const FormAction = ({ children = t('steps.plan.form'), ...props }: ButtonProps) => - + + const TemplateAction = (props: ButtonProps) => + const ContactAction = (props: ButtonProps) => @@ -31,7 +36,7 @@ const PlanActions = () => { switch (status) { case "awaiting": return - + case "accepted": return @@ -41,16 +46,14 @@ const PlanActions = () => { case "declined": return { t('fix-errors') } + + case "draft": return - - + + 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. + Wypełnij i zeskanuj Indywidualny program Praktyk a następnie wyślij go z pomocą tego formularza. 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: -- 2.45.2 From a78f5d365ee7497e7218d65d14135162580d8c41 Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Wed, 5 Aug 2020 22:50:57 +0200 Subject: [PATCH 2/4] Add insurance step --- src/data/edition.ts | 1 + src/pages/main.tsx | 5 ++++- src/pages/steps/common.tsx | 9 ++++++++- src/pages/steps/insurance.tsx | 27 +++++++++++++++++++++++++++ src/pages/steps/plan.tsx | 7 ++----- src/pages/steps/proposal.tsx | 9 +++------ src/state/actions/index.ts | 5 +++-- src/state/actions/insurance.ts | 12 ++++++++++++ src/state/reducer/index.ts | 2 ++ src/state/reducer/insurance.ts | 26 ++++++++++++++++++++++++++ translations/pl.yaml | 2 ++ 11 files changed, 90 insertions(+), 15 deletions(-) create mode 100644 src/pages/steps/insurance.tsx create mode 100644 src/state/actions/insurance.ts create mode 100644 src/state/reducer/insurance.ts diff --git a/src/data/edition.ts b/src/data/edition.ts index 8a29c94..7fc5438 100644 --- a/src/data/edition.ts +++ b/src/data/edition.ts @@ -11,6 +11,7 @@ export type Deadlines = { proposal?: Moment; personalPlan?: Moment; report?: Moment; + insurance?: Moment; } export function getEditionDeadlines(edition: Edition): Deadlines { diff --git a/src/pages/main.tsx b/src/pages/main.tsx index 3ddcfef..5d2da88 100644 --- a/src/pages/main.tsx +++ b/src/pages/main.tsx @@ -11,12 +11,15 @@ import { Deadlines, Edition, getEditionDeadlines } from "@/data/edition"; import { Step } from "@/components"; import { ProposalStep } from "@/pages/steps/proposal"; import { PlanStep } from "@/pages/steps/plan"; +import { InsuranceStep } from "@/pages/steps/insurance"; +import { InsuranceState } from "@/state/reducer/insurance"; export const MainPage = () => { const { t } = useTranslation(); const student = useSelector(state => state.student); const deadlines = useSelector(state => getEditionDeadlines(state.edition as Edition)); // edition cannot be null at this point + const insurance = useSelector(root => root.insurance); const missingStudentData = useMemo(() => student ? getMissingStudentData(student) : [], [student]); @@ -39,7 +42,7 @@ export const MainPage = () => { - + { insurance.required && } diff --git a/src/pages/steps/common.tsx b/src/pages/steps/common.tsx index 261ba52..58fdb8e 100644 --- a/src/pages/steps/common.tsx +++ b/src/pages/steps/common.tsx @@ -1,8 +1,9 @@ import { getSubmissionStatus, SubmissionState, SubmissionStatus } from "@/state/reducer/submission"; -import { Theme } from "@material-ui/core"; +import { Button, ButtonProps, Theme } from "@material-ui/core"; import { createStyles, makeStyles } from "@material-ui/core/styles"; import { useTranslation } from "react-i18next"; import React from "react"; +import { CommentQuestion } from "mdi-material-ui/index"; export const getColorByStatus = (status: SubmissionStatus, theme: Theme) => { switch (status) { @@ -44,3 +45,9 @@ export const Status = ({ submission } : SubmissionStatusProps) => { return { t(`submission.status.${ status }`) }; } + +export const ContactAction = (props: ButtonProps) => { + const { t } = useTranslation(); + + return +} diff --git a/src/pages/steps/insurance.tsx b/src/pages/steps/insurance.tsx new file mode 100644 index 0000000..2245c53 --- /dev/null +++ b/src/pages/steps/insurance.tsx @@ -0,0 +1,27 @@ +import { useSelector } from "react-redux"; +import { AppState } from "@/state/reducer"; +import { InsuranceState } from "@/state/reducer/insurance"; +import { Actions, Step } from "@/components"; +import { useTranslation } from "react-i18next"; +import React from "react"; +import { Edition, getEditionDeadlines } from "@/data/edition"; +import { Moment } from "moment"; +import { ContactAction } from "@/pages/steps/common"; + +export const InsuranceStep = () => { + const insurance = useSelector(root => root.insurance); + const deadline = useSelector(state => getEditionDeadlines(state.edition as Edition).insurance); // edition cannot be null at this point + const { t } = useTranslation(); + + // we don't want to show this step unless it's required + if (!insurance.required) { + return null; + } + + return +

{ t(`steps.insurance.instructions`) }

+ + + +
+} diff --git a/src/pages/steps/plan.tsx b/src/pages/steps/plan.tsx index e92169d..7a94c7f 100644 --- a/src/pages/steps/plan.tsx +++ b/src/pages/steps/plan.tsx @@ -3,14 +3,14 @@ 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, FileDownloadOutline, FileUploadOutline } from "mdi-material-ui/index"; +import { FileDownloadOutline, FileUploadOutline } from "mdi-material-ui/index"; import { route } from "@/routing"; import { Link as RouterLink } from "react-router-dom"; import { Actions, Step } from "@/components"; import React, { HTMLProps } from "react"; import { Alert, AlertTitle } from "@material-ui/lab"; import { Deadlines, Edition, getEditionDeadlines } from "@/data/edition"; -import { Status } from "@/pages/steps/common"; +import { ContactAction, Status } from "@/pages/steps/common"; import { Description as DescriptionIcon } from "@material-ui/icons"; const PlanActions = () => { @@ -30,9 +30,6 @@ const PlanActions = () => { { t('steps.plan.template') } - const ContactAction = (props: ButtonProps) => - - switch (status) { case "awaiting": return diff --git a/src/pages/steps/proposal.tsx b/src/pages/steps/proposal.tsx index 5565cdc..b6f6cd1 100644 --- a/src/pages/steps/proposal.tsx +++ b/src/pages/steps/proposal.tsx @@ -10,8 +10,8 @@ import { Deadlines, Edition, getEditionDeadlines } from "@/data/edition"; import { Actions, Step } from "@/components"; import { route } from "@/routing"; import { Link as RouterLink } from "react-router-dom"; -import { ClipboardEditOutline, CommentQuestion, FileFind } from "mdi-material-ui/index"; -import { Status } from "@/pages/steps/common"; +import { ClipboardEditOutline, FileFind } from "mdi-material-ui/index"; +import { ContactAction, Status } from "@/pages/steps/common"; const ProposalActions = () => { const status = useSelector(state => getSubmissionStatus(state.proposal)); @@ -26,9 +26,6 @@ const ProposalActions = () => { { children } - const ContactAction = (props: ButtonProps) => - - switch (status) { case "awaiting": return @@ -42,7 +39,7 @@ const ProposalActions = () => { case "declined": return { t('fix-errors') } - + case "draft": return diff --git a/src/state/actions/index.ts b/src/state/actions/index.ts index f5bcdfb..54ac996 100644 --- a/src/state/actions/index.ts +++ b/src/state/actions/index.ts @@ -6,6 +6,7 @@ import { Dispatch } from "react"; import { useDispatch as useReduxDispatch } from "react-redux"; import { InternshipPlanAction, InternshipPlanActions } from "@/state/actions/plan"; +import { InsuranceAction, InsuranceActions } from "@/state/actions/insurance"; export * from "./base" export * from "./edition" @@ -14,9 +15,9 @@ export * from "./student" export * from "./proposal" export * from "./plan" -export type Action = StudentAction | EditionAction | SettingsAction | InternshipProposalAction | InternshipPlanAction; +export type Action = StudentAction | EditionAction | SettingsAction | InternshipProposalAction | InternshipPlanAction | InsuranceAction; -export const Actions = { ...StudentActions, ...EditionActions, ...SettingActions, ...InternshipProposalActions, ...InternshipPlanActions } +export const Actions = { ...StudentActions, ...EditionActions, ...SettingActions, ...InternshipProposalActions, ...InternshipPlanActions, ...InsuranceActions } export type Actions = typeof Actions; export const useDispatch = () => useReduxDispatch>() diff --git a/src/state/actions/insurance.ts b/src/state/actions/insurance.ts new file mode 100644 index 0000000..721d7d6 --- /dev/null +++ b/src/state/actions/insurance.ts @@ -0,0 +1,12 @@ +import { Action } from "@/state/actions/base"; +import { InsuranceState } from "@/state/reducer/insurance"; + +export enum InsuranceActions { + Signed = "RECEIVE_INSURANCE_SIGN", + Update = "RECEIVE_INSURANCE_UPDATE", +} + +export type InsuranceSigned = Action; +export type InsuranceUpdate = Action & Partial; + +export type InsuranceAction = InsuranceSigned | InsuranceUpdate; diff --git a/src/state/reducer/index.ts b/src/state/reducer/index.ts index 3d139e2..ca5d238 100644 --- a/src/state/reducer/index.ts +++ b/src/state/reducer/index.ts @@ -5,6 +5,7 @@ import editionReducer from "@/state/reducer/edition"; import settingsReducer from "@/state/reducer/settings"; import internshipProposalReducer from "@/state/reducer/proposal"; import internshipPlanReducer from "@/state/reducer/plan"; +import { insuranceReducer } from "@/state/reducer/insurance"; const rootReducer = combineReducers({ student: studentReducer, @@ -12,6 +13,7 @@ const rootReducer = combineReducers({ settings: settingsReducer, proposal: internshipProposalReducer, plan: internshipPlanReducer, + insurance: insuranceReducer, }) export type AppState = ReturnType; diff --git a/src/state/reducer/insurance.ts b/src/state/reducer/insurance.ts new file mode 100644 index 0000000..d5aaa4f --- /dev/null +++ b/src/state/reducer/insurance.ts @@ -0,0 +1,26 @@ +import { Reducer } from "react"; +import { InsuranceAction, InsuranceActions } from "@/state/actions/insurance"; + +export type InsuranceState = { + required: boolean; + signed: boolean; + /// other data? +} + +const initialInsuranceState: InsuranceState = { + required: false, + signed: false, +} + +export const insuranceReducer: Reducer = (state = initialInsuranceState, action) => { + const { type, ...payload } = action; + + switch (action.type) { + case InsuranceActions.Signed: + return { ...state, signed: true } + case InsuranceActions.Update: + return { ...state, ...payload } + default: + return state; + } +} diff --git a/translations/pl.yaml b/translations/pl.yaml index 07be4d1..2cfd0fa 100644 --- a/translations/pl.yaml +++ b/translations/pl.yaml @@ -95,5 +95,7 @@ steps: header: "Ocena z praktyki" insurance: header: "Ubezpieczenie NNW" + instructions: > + papierki do podpisania... contact-coordinator: "Skontaktuj się z koordynatorem" -- 2.45.2 From f834c3675dba2d81a15b13e879c92001a6cee639 Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Sun, 9 Aug 2020 19:21:47 +0200 Subject: [PATCH 3/4] Add simple proposal previwe --- src/components/proposalPreview.tsx | 75 ++++++++++++++++++++++++++++++ src/forms/internship.tsx | 8 ++-- src/forms/plan.tsx | 2 +- src/i18n.ts | 5 ++ src/pages/index.ts | 4 -- src/pages/internship/proposal.tsx | 31 ++++++++++-- src/pages/steps/proposal.tsx | 6 ++- src/routing.tsx | 5 +- src/styles/page.scss | 4 ++ src/utils/numbers.ts | 32 +++++++++++++ translations/pl.yaml | 21 ++++++++- 11 files changed, 177 insertions(+), 16 deletions(-) create mode 100644 src/components/proposalPreview.tsx create mode 100644 src/utils/numbers.ts diff --git a/src/components/proposalPreview.tsx b/src/components/proposalPreview.tsx new file mode 100644 index 0000000..96a5d9b --- /dev/null +++ b/src/components/proposalPreview.tsx @@ -0,0 +1,75 @@ +import { Internship } from "@/data"; +import React from "react"; +import { Paper, PaperProps, Typography, TypographyProps } from "@material-ui/core"; +import { useTranslation } from "react-i18next"; +import { createStyles, makeStyles } from "@material-ui/core/styles"; +import classNames from "classnames"; + +export type ProposalPreviewProps = { + proposal: Internship; +} + +const Label = ({ children }: TypographyProps) => { + return { children } +} + +const useSectionStyles = makeStyles(theme => createStyles({ + root: { + padding: theme.spacing(2), + marginTop: theme.spacing(3) + } +})) + +const Section = ({ children, ...props }: PaperProps) => { + const classes = useSectionStyles(); + + return + { children } + +} + +export const ProposalPreview = ({ proposal }: ProposalPreviewProps) => { + const { t } = useTranslation(); + + return
+ { proposal.intern.name } { proposal.intern.surname } + + { t('internship.intern.semester', { semester: proposal.intern.semester }) } + { ", " } + { t('internship.intern.album', { album: proposal.intern.albumNumber }) } + + +
+ + { proposal.type } +
+ +
+ + + { t('internship.date-range', { start: proposal.startDate, end: proposal.endDate }) } + + + { t('internship.duration', { duration: 0 })} + { ", " } + { t('internship.hours', { hours: proposal.hours })} + +
+ +
+ + + { proposal.company.name } + + + NIP: { proposal.company.nip } + +
+ +
+ + { t('internship.address.city', proposal.office.address) } + { t('internship.address.street', proposal.office.address) } +
+
+} diff --git a/src/forms/internship.tsx b/src/forms/internship.tsx index 752bf28..fb5b9ca 100644 --- a/src/forms/internship.tsx +++ b/src/forms/internship.tsx @@ -182,13 +182,13 @@ export const InternshipForm: React.FunctionComponent = prop return (
- Dane osoby odbywającej praktykę + { t('internship.intern-info') } - Rodzaj i program praktyki + { t('internship.kind' )} - Czas trwania praktyki + { t('internship.duration') } - Miejsce odbywania praktyki + { t('internship.place') } diff --git a/src/forms/plan.tsx b/src/forms/plan.tsx index 24a8fa7..0c96203 100644 --- a/src/forms/plan.tsx +++ b/src/forms/plan.tsx @@ -32,7 +32,7 @@ export const PlanForm = () => { - + { t('forms.plan.dropzone-help') } diff --git a/src/i18n.ts b/src/i18n.ts index eb71721..c01bc57 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -5,6 +5,7 @@ import I18nextBrowserLanguageDetector from "i18next-browser-languagedetector"; import "moment/locale/pl" import "moment/locale/en-gb" import moment, { isDuration, isMoment } from "moment"; +import { convertToRoman } from "@/utils/numbers"; const resources = { en: { @@ -24,6 +25,10 @@ i18n interpolation: { escapeValue: false, format: (value, format, lng) => { + if (typeof value === "number" && format == "roman") { + return convertToRoman(value); + } + if (isMoment(value)) { return value.locale(lng || "pl").format(format || "DD MMM YYYY"); } diff --git a/src/pages/index.ts b/src/pages/index.ts index bb1a4b5..c5f71a3 100644 --- a/src/pages/index.ts +++ b/src/pages/index.ts @@ -1,7 +1,3 @@ export * from "./internship/proposal"; export * from "./errors/not-found" export * from "./main" -export { ProposalStep } from "@/pages/steps/proposal"; -export { ProposalComment } from "@/pages/steps/proposal"; -export { ProposalActions } from "@/pages/steps/proposal"; -export { ProposalStatus } from "@/pages/steps/proposal"; diff --git a/src/pages/internship/proposal.tsx b/src/pages/internship/proposal.tsx index e45b4cb..09b8ca8 100644 --- a/src/pages/internship/proposal.tsx +++ b/src/pages/internship/proposal.tsx @@ -4,9 +4,15 @@ import { Link as RouterLink } from "react-router-dom"; import { route } from "@/routing"; import { InternshipForm } from "@/forms/internship"; import React from "react"; -import { ProposalComment } from "@/pages"; +import { ProposalComment } from "@/pages/steps/proposal"; +import { useTranslation } from "react-i18next"; +import { ProposalPreview } from "@/components/proposalPreview"; +import { useSelector } from "react-redux"; +import { Internship } from "@/data"; +import { AppState } from "@/state/reducer"; +import { internshipSerializationTransformer } from "@/serialization"; -export const InternshipProposalPage = () => { +export const InternshipProposalFormPage = () => { return @@ -22,4 +28,23 @@ export const InternshipProposalPage = () => { } -export default InternshipProposalPage; +export const InternshipProposalPreviewPage = () => { + const { t } = useTranslation(); + const proposal = useSelector(state => state.proposal.proposal && internshipSerializationTransformer.reverseTransform(state.proposal.proposal)); + + return + + + Moja praktyka + Podgląd zgłoszenia + + Moje zgłoszenie + + + + { proposal && } + + +} + +export default InternshipProposalFormPage; diff --git a/src/pages/steps/proposal.tsx b/src/pages/steps/proposal.tsx index b6f6cd1..f7646d9 100644 --- a/src/pages/steps/proposal.tsx +++ b/src/pages/steps/proposal.tsx @@ -18,7 +18,11 @@ const ProposalActions = () => { const { t } = useTranslation(); const ReviewAction = (props: ButtonProps) => - + const FormAction = ({ children = t('steps.internship-proposal.form'), ...props }: ButtonProps) => +
} diff --git a/src/forms/internship.tsx b/src/forms/internship.tsx index fb5b9ca..f4d2324 100644 --- a/src/forms/internship.tsx +++ b/src/forms/internship.tsx @@ -182,13 +182,13 @@ export const InternshipForm: React.FunctionComponent = prop return (
- { t('internship.intern-info') } + { t('internship.sections.intern-info') } - { t('internship.kind' )} + { t('internship.sections.kind' )} - { t('internship.duration') } + { t('internship.sections.duration') } - { t('internship.place') } + { t('internship.sections.place') } diff --git a/src/hooks/useProxyState.ts b/src/hooks/useProxyState.ts index 3dd51fa..87b7945 100644 --- a/src/hooks/useProxyState.ts +++ b/src/hooks/useProxyState.ts @@ -1,9 +1,10 @@ -import { Dispatch, SetStateAction, useEffect, useState } from "react"; +import { Dispatch, SetStateAction, useState } from "react"; export function useProxyState(initial: T, setter: (value: T) => void): [T, Dispatch>] { const [value, proxy] = useState(initial); - useEffect(() => setter(value), [ value ]); - - return [value, proxy]; + return [value, (newValue: SetStateAction) => { + proxy(newValue); + setter(typeof newValue === "function" ? (newValue as any)(value) : newValue); + }]; } diff --git a/src/serialization/internship.ts b/src/serialization/internship.ts index be27ddf..9a9f628 100644 --- a/src/serialization/internship.ts +++ b/src/serialization/internship.ts @@ -1,6 +1,7 @@ import { Internship, InternshipType } from "@/data"; import { Serializable, SerializationTransformer } from "@/serialization/types"; import { momentSerializationTransformer } from "@/serialization/moment"; +import { Moment } from "moment"; export const internshipSerializationTransformer: SerializationTransformer = { transform: (internship: Internship): Serializable => ({ @@ -10,8 +11,8 @@ export const internshipSerializationTransformer: SerializationTransformer): Internship => ({ ...serialized, - startDate: momentSerializationTransformer.reverseTransform(serialized.startDate), - endDate: momentSerializationTransformer.reverseTransform(serialized.endDate), + startDate: momentSerializationTransformer.reverseTransform(serialized.startDate) as Moment, + endDate: momentSerializationTransformer.reverseTransform(serialized.endDate) as Moment, type: serialized.type as InternshipType, }), } diff --git a/src/styles/index.ts b/src/styles/index.ts new file mode 100644 index 0000000..c7b6bdf --- /dev/null +++ b/src/styles/index.ts @@ -0,0 +1 @@ +export * from "./spacing" diff --git a/src/styles/page.scss b/src/styles/page.scss index f81763a..f6a1b68 100644 --- a/src/styles/page.scss +++ b/src/styles/page.scss @@ -16,3 +16,7 @@ .proposal__primary { font-size: 1.675rem; } + +.proposal__header:not(:first-child) { + margin-top: 1rem; +} diff --git a/src/styles/spacing.ts b/src/styles/spacing.ts new file mode 100644 index 0000000..dc8863d --- /dev/null +++ b/src/styles/spacing.ts @@ -0,0 +1,19 @@ +import { createStyles, makeStyles } from "@material-ui/core/styles"; + +const defaultSpacing: number = 3; + +export const useVerticalSpacing = makeStyles(theme => createStyles({ + root: { + "& > *:not(:last-child)": { + marginBottom: (spacing: number = defaultSpacing) => theme.spacing(spacing) + } + } +})) + +export const useHorizontalSpacing = makeStyles(theme => createStyles({ + root: { + "& > *:not(:last-child)": { + marginRight: (spacing: number = defaultSpacing) => theme.spacing(spacing) + } + } +})) diff --git a/translations/pl.yaml b/translations/pl.yaml index ac7d8dd..c52c43d 100644 --- a/translations/pl.yaml +++ b/translations/pl.yaml @@ -57,7 +57,7 @@ internship: semester: semestr {{ semester, roman }} album: "numer albumu {{ album }}" date-range: "{{ start, DD MMMM YYYY }} - {{ end, DD MMMM YYYY }}" - duration: "{{ duration, humanize }} tygodni" + duration: "{{ duration, humanize }}" hours: "{{ hours }} godzin" office: "Oddział / adres" address: @@ -68,6 +68,7 @@ internship: duration: "Czas trwania praktyki" place: "Miejsce odbywania praktyki" kind: "Rodzaj i program praktyki" + mentor: "Zakładowy opiekun praktyki" steps: -- 2.45.2