polish up internship proposal preview

This commit is contained in:
Kacper Donat 2020-08-10 20:11:30 +02:00
parent 5316630a29
commit fb03b892a2
9 changed files with 84 additions and 43 deletions

View File

@ -1,14 +1,8 @@
import React, { HTMLProps } from "react";
import { makeStyles } from "@material-ui/core/styles";
import { useHorizontalSpacing } from "@/styles";
export const Actions = (props: HTMLProps<HTMLDivElement>) => {
const classes = makeStyles(theme => ({
root: {
"& > *": {
marginRight: theme.spacing(1)
}
}
}))();
const classes = useHorizontalSpacing(1);
return <div className={ classes.root } { ...props }/>
}

View File

@ -1,9 +1,14 @@
import { Internship } from "@/data";
import { Internship, internshipTypeLabels } from "@/data";
import React from "react";
import { Paper, PaperProps, Typography, TypographyProps } from "@material-ui/core";
import { Button, 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";
import { Link as RouterLink } from "react-router-dom";
import { route } from "@/routing";
import { Actions } from "@/components/actions";
import { useVerticalSpacing } from "@/styles";
import moment from "moment";
export type ProposalPreviewProps = {
proposal: Internship;
@ -16,7 +21,6 @@ const Label = ({ children }: TypographyProps) => {
const useSectionStyles = makeStyles(theme => createStyles({
root: {
padding: theme.spacing(2),
marginTop: theme.spacing(3)
}
}))
@ -31,30 +35,19 @@ const Section = ({ children, ...props }: PaperProps) => {
export const ProposalPreview = ({ proposal }: ProposalPreviewProps) => {
const { t } = useTranslation();
return <div className="proposal">
<Typography className="proposal__primary">{ proposal.intern.name } { proposal.intern.surname }</Typography>
<Typography className="proposal__secondary">
{ t('internship.intern.semester', { semester: proposal.intern.semester }) }
{ ", " }
{ t('internship.intern.album', { album: proposal.intern.albumNumber }) }
</Typography>
const classes = useVerticalSpacing(3);
<Section>
<Label>{ t('internship.sections.kind') }</Label>
<Typography className="proposal__primary">{ proposal.type }</Typography>
</Section>
const duration = moment.duration(proposal.endDate.diff(proposal.startDate));
<Section>
<Label>{ t('internship.sections.duration') }</Label>
<Typography className="proposal__primary">
{ t('internship.date-range', { start: proposal.startDate, end: proposal.endDate }) }
</Typography>
return <div className={ classNames("proposal", classes.root) }>
<div>
<Typography className="proposal__primary">{ proposal.intern.name } { proposal.intern.surname }</Typography>
<Typography className="proposal__secondary">
{ t('internship.duration', { duration: 0 })}
{ t('internship.intern.semester', { semester: proposal.intern.semester }) }
{ ", " }
{ t('internship.hours', { hours: proposal.hours })}
{ t('internship.intern.album', { album: proposal.intern.albumNumber }) }
</Typography>
</Section>
</div>
<Section>
<Label>{ t('internship.sections.place') }</Label>
@ -64,12 +57,39 @@ export const ProposalPreview = ({ proposal }: ProposalPreviewProps) => {
<Typography className="proposal__secondary">
NIP: { proposal.company.nip }
</Typography>
</Section>
<Section>
<Label>{ t('internship.office') }</Label>
<Typography className="proposal__primary">{ t('internship.address.city', proposal.office.address) }</Typography>
<Typography className="proposal__secondary">{ t('internship.address.street', proposal.office.address) }</Typography>
</Section>
<Section>
<Label>{ t('internship.sections.kind') }</Label>
<Typography className="proposal__primary">{ internshipTypeLabels[proposal.type].label }</Typography>
</Section>
<Section>
<Label>{ t('internship.sections.duration') }</Label>
<Typography className="proposal__primary">
{ t('internship.date-range', { start: proposal.startDate, end: proposal.endDate }) }
</Typography>
<Typography className="proposal__secondary">
{ t('internship.duration', { duration }) }
{ ", " }
{ t('internship.hours', { hours: proposal.hours }) }
</Typography>
</Section>
<Section>
<Label>{ t('internship.sections.mentor') }</Label>
<Typography className="proposal__primary">{ proposal.mentor.name } { proposal.mentor.surname }</Typography>
<Typography className="proposal__secondary">{ proposal.mentor.email }, { proposal.mentor.phone }</Typography>
</Section>
<Actions>
<Button component={ RouterLink } to={ route("home") } variant="contained" color="primary">
{ t('go-back') }
</Button>
</Actions>
</div>
}

View File

@ -182,13 +182,13 @@ export const InternshipForm: React.FunctionComponent<InternshipFormProps> = prop
return (
<div className="internship-form">
<Typography variant="h3" className="section-header">{ t('internship.intern-info') }</Typography>
<Typography variant="h3" className="section-header">{ t('internship.sections.intern-info') }</Typography>
<StudentForm student={ sampleStudent }/>
<Typography variant="h3" className="section-header">{ t('internship.kind' )}</Typography>
<Typography variant="h3" className="section-header">{ t('internship.sections.kind' )}</Typography>
<InternshipProgramForm internship={ internship } onChange={ setInternship }/>
<Typography variant="h3" className="section-header">{ t('internship.duration') }</Typography>
<Typography variant="h3" className="section-header">{ t('internship.sections.duration') }</Typography>
<InternshipDurationForm internship={ internship } onChange={ setInternship }/>
<Typography variant="h3" className="section-header">{ t('internship.place') }</Typography>
<Typography variant="h3" className="section-header">{ t('internship.sections.place') }</Typography>
<CompanyForm internship={ internship } onChange={ setInternship }/>
<Actions>
<Button variant="contained" color="primary" onClick={ handleSubmitConfirmation }>{ t("confirm") }</Button>

View File

@ -1,9 +1,10 @@
import { Dispatch, SetStateAction, useEffect, useState } from "react";
import { Dispatch, SetStateAction, useState } from "react";
export function useProxyState<T>(initial: T, setter: (value: T) => void): [T, Dispatch<SetStateAction<T>>] {
const [value, proxy] = useState<T>(initial);
useEffect(() => setter(value), [ value ]);
return [value, proxy];
return [value, (newValue: SetStateAction<T>) => {
proxy(newValue);
setter(typeof newValue === "function" ? (newValue as any)(value) : newValue);
}];
}

View File

@ -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<Internship> = {
transform: (internship: Internship): Serializable<Internship> => ({
@ -10,8 +11,8 @@ export const internshipSerializationTransformer: SerializationTransformer<Intern
}),
reverseTransform: (serialized: Serializable<Internship>): 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,
}),
}

1
src/styles/index.ts Normal file
View File

@ -0,0 +1 @@
export * from "./spacing"

View File

@ -16,3 +16,7 @@
.proposal__primary {
font-size: 1.675rem;
}
.proposal__header:not(:first-child) {
margin-top: 1rem;
}

19
src/styles/spacing.ts Normal file
View File

@ -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)
}
}
}))

View File

@ -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: