add CheckMobileApp/Professions sections

This commit is contained in:
Dawid Wysokiński 2021-03-27 10:19:31 +01:00
parent e03fe701e0
commit 11df56b5e2
9 changed files with 179 additions and 42 deletions

View File

@ -14,6 +14,8 @@ import Header from './components/Header/Header';
import Timer from './components/Timer/Timer';
import AboutExam from './components/AboutExam/AboutExam';
import ExamParts from './components/ExamParts/ExamParts';
import CheckMobileApp from './components/CheckMobileApp/CheckMobileApp';
import Professions from './components/Professions/Professions';
interface IndexPageProps {
professions: Profession[];
@ -21,7 +23,11 @@ interface IndexPageProps {
dateOfTheExam: string;
}
const IndexPage = ({ qualifications, dateOfTheExam }: IndexPageProps) => {
const IndexPage = ({
qualifications,
dateOfTheExam,
professions,
}: IndexPageProps) => {
return (
<Layout padding={false}>
<Header qualifications={qualifications} />
@ -29,6 +35,8 @@ const IndexPage = ({ qualifications, dateOfTheExam }: IndexPageProps) => {
<AboutExam />
<Divider />
<ExamParts />
<CheckMobileApp />
<Professions professions={professions} />
</Layout>
);
};

View File

@ -3,7 +3,7 @@ import React from 'react';
import { Container, Typography } from '@material-ui/core';
import Section, { Size } from '../Section/Section';
function AboutExam() {
const AboutExam = () => {
return (
<Section size={Size.Medium}>
<Container>
@ -19,6 +19,6 @@ function AboutExam() {
</Container>
</Section>
);
}
};
export default AboutExam;

View File

@ -0,0 +1,29 @@
import React from 'react';
import { GOOGLE_PLAY_URL } from 'config/app';
import { Container, Typography } from '@material-ui/core';
import Link from 'common/Link/Link';
import Section, { BgColor } from '../Section/Section';
const CheckMobileApp = () => {
return (
<Section bgColor={BgColor.Primary}>
<Container>
<Typography align="center" gutterBottom variant="h3" component="h2">
Nie zapomnij sprawdzić naszej aplikacji mobilnej!
</Typography>
<Typography align="center">
<Link href={GOOGLE_PLAY_URL} title="Pobierz z Google Play">
<img
style={{ width: '200px' }}
src="/images/google-play-badge.svg"
alt="Pobierz z Google Play"
/>
</Link>
</Typography>
</Container>
</Section>
);
};
export default CheckMobileApp;

View File

@ -3,7 +3,7 @@ import { makeStyles } from '@material-ui/core/styles';
import { Typography, Container, Grid } from '@material-ui/core';
import Section, { Size } from '../Section/Section';
function AboutSection() {
const ExamParts = () => {
const classes = useStyles();
return (
<Section size={Size.Medium}>
@ -16,7 +16,7 @@ function AboutSection() {
<div className={classes.imageWrapper}>
<Image
src="/images/written-part.png"
alt="Część pisemna"
alt="Egzamin zawodowy - Część pisemna"
width={608}
height={408}
/>
@ -33,7 +33,7 @@ function AboutSection() {
<div className={classes.imageWrapper}>
<Image
src="/images/practical-part.png"
alt="Część praktyczna"
alt="Egzamin zawodowy - Część praktyczna"
width={608}
height={408}
/>
@ -50,7 +50,7 @@ function AboutSection() {
</Container>
</Section>
);
}
};
const useStyles = makeStyles(theme => ({
examPart: {
@ -64,4 +64,4 @@ const useStyles = makeStyles(theme => ({
},
}));
export default AboutSection;
export default ExamParts;

View File

@ -70,8 +70,8 @@ const useStyles = makeStyles(theme => ({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
paddingTop: theme.spacing(3),
paddingBottom: theme.spacing(3),
paddingTop: theme.spacing(5),
paddingBottom: theme.spacing(5),
},
imageWrapper: {
textAlign: 'center',

View File

@ -0,0 +1,96 @@
import { useMemo } from 'react';
import { groupBy } from 'lodash';
import { polishPlurals } from 'polish-plurals';
import { Profession as ProfessionT } from 'libs/graphql';
import { QUESTIONS } from 'config/app';
import { Route } from 'config/routing';
import { makeStyles } from '@material-ui/core/styles';
import {
Accordion,
AccordionSummary,
Typography,
AccordionDetails,
} from '@material-ui/core';
import { ExpandMore as ExpandMoreIcon } from '@material-ui/icons';
import Link from 'common/Link/Link';
export interface ProfessionProps {
profession: ProfessionT;
}
const Profession = ({ profession }: ProfessionProps) => {
const classes = useStyles();
const qualificationsByFormula = useMemo(() => {
return groupBy(profession.qualifications, 'formula');
}, [profession]);
return (
<Accordion>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography variant="h4">{profession.name}</Typography>
</AccordionSummary>
<AccordionDetails className={classes.accordionDetails}>
{profession.qualifications.length > 0 ? (
Object.keys(qualificationsByFormula).map(formula => {
const qualifications = qualificationsByFormula[formula];
return (
<div key={formula}>
<Typography variant="h5">{formula}</Typography>
{qualifications.map(qualification => {
return (
<Typography key={qualification.id}>
<strong>
{qualification.name} ({qualification.code})
</strong>{' '}
-&gt;{' '}
{QUESTIONS.map(howManyQuestions => {
return (
<Link
key={howManyQuestions}
href={{
pathname: Route.TestPage,
query: {
slug: qualification.slug,
questions: howManyQuestions,
},
}}
>
Test {howManyQuestions}{' '}
{polishPlurals(
'pytanie',
'pytania',
'pytań',
howManyQuestions
)}{' '}
</Link>
);
})}
</Typography>
);
})}
</div>
);
})
) : (
<Typography>
Żadna kwalifikacja nie została przypisana do zawodu{' '}
{profession.name}
</Typography>
)}
</AccordionDetails>
</Accordion>
);
};
const useStyles = makeStyles(theme => {
return {
accordionDetails: {
'& > *:not(:last-child)': {
marginBottom: theme.spacing(1),
},
},
};
});
export default Profession;

View File

@ -0,0 +1,26 @@
import { Profession as ProfessionT } from 'libs/graphql';
import { Container, Typography } from '@material-ui/core';
import Section, { Size } from '../Section/Section';
import Profession from './Profession';
export interface ProfessionsProps {
professions: ProfessionT[];
}
const Professions = ({ professions }: ProfessionsProps) => {
return (
<Section size={Size.Medium}>
<Container>
<Typography align="center" variant="h2" gutterBottom>
Lista dostępnych zawodów i kwalifikacji
</Typography>
{professions.map(profession => {
return <Profession profession={profession} key={profession.id} />;
})}
</Container>
</Section>
);
};
export default Professions;

View File

@ -12,6 +12,7 @@ export const QUERY_PROFESSIONS = gql`
slug
code
name
formula
}
}
}

View File

@ -1,7 +1,11 @@
export type Maybe<T> = T | null;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
export type Exact<T extends { [key: string]: unknown }> = {
[K in keyof T]: T[K];
};
export type MakeOptional<T, K extends keyof T> = Omit<T, K> &
{ [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> &
{ [SubKey in K]: Maybe<T[SubKey]> };
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: number;
@ -13,9 +17,6 @@ export type Scalars = {
Upload: any;
};
export type Question = {
id: Scalars['ID'];
from?: Maybe<Scalars['String']>;
@ -88,17 +89,16 @@ export type QuestionFilter = {
export enum Role {
Admin = 'admin',
User = 'user'
User = 'user',
}
export enum Answer {
A = 'a',
B = 'b',
C = 'c',
D = 'd'
D = 'd',
}
export type UserInput = {
displayName?: Maybe<Scalars['String']>;
password?: Maybe<Scalars['String']>;
@ -119,7 +119,6 @@ export type Query = {
me?: Maybe<User>;
};
export type QueryProfessionsArgs = {
filter?: Maybe<ProfessionFilter>;
limit?: Maybe<Scalars['Int']>;
@ -127,13 +126,11 @@ export type QueryProfessionsArgs = {
sort?: Maybe<Array<Scalars['String']>>;
};
export type QueryProfessionArgs = {
id?: Maybe<Scalars['Int']>;
slug?: Maybe<Scalars['String']>;
};
export type QueryQualificationsArgs = {
filter?: Maybe<QualificationFilter>;
limit?: Maybe<Scalars['Int']>;
@ -141,13 +138,11 @@ export type QueryQualificationsArgs = {
sort?: Maybe<Array<Scalars['String']>>;
};
export type QueryQualificationArgs = {
id?: Maybe<Scalars['Int']>;
slug?: Maybe<Scalars['String']>;
};
export type QueryQuestionsArgs = {
filter?: Maybe<QuestionFilter>;
limit?: Maybe<Scalars['Int']>;
@ -155,13 +150,11 @@ export type QueryQuestionsArgs = {
sort?: Maybe<Array<Scalars['String']>>;
};
export type QueryGenerateTestArgs = {
qualificationIDs: Array<Scalars['ID']>;
limit?: Maybe<Scalars['Int']>;
};
export type QueryUsersArgs = {
filter?: Maybe<UserFilter>;
limit?: Maybe<Scalars['Int']>;
@ -169,7 +162,6 @@ export type QueryUsersArgs = {
sort?: Maybe<Array<Scalars['String']>>;
};
export type QueryUserArgs = {
id: Scalars['Int'];
};
@ -190,7 +182,6 @@ export type QualificationFilterOr = {
codeIEQ?: Maybe<Scalars['String']>;
};
export type UserFilter = {
id?: Maybe<Array<Scalars['ID']>>;
idNEQ?: Maybe<Array<Scalars['ID']>>;
@ -263,77 +254,63 @@ export type Mutation = {
signIn?: Maybe<UserWithToken>;
};
export type MutationCreateProfessionArgs = {
input: ProfessionInput;
};
export type MutationUpdateProfessionArgs = {
id: Scalars['ID'];
input: ProfessionInput;
};
export type MutationDeleteProfessionsArgs = {
ids: Array<Scalars['ID']>;
};
export type MutationCreateQualificationArgs = {
input: QualificationInput;
};
export type MutationUpdateQualificationArgs = {
id: Scalars['ID'];
input: QualificationInput;
};
export type MutationDeleteQualificationsArgs = {
ids: Array<Scalars['ID']>;
};
export type MutationCreateQuestionArgs = {
input: QuestionInput;
};
export type MutationUpdateQuestionArgs = {
id: Scalars['ID'];
input: QuestionInput;
};
export type MutationDeleteQuestionsArgs = {
ids: Array<Scalars['ID']>;
};
export type MutationCreateUserArgs = {
input: UserInput;
};
export type MutationUpdateUserArgs = {
id: Scalars['ID'];
input: UserInput;
};
export type MutationUpdateManyUsersArgs = {
ids: Array<Scalars['ID']>;
input: UpdateManyUsersInput;
};
export type MutationDeleteUsersArgs = {
ids: Array<Scalars['ID']>;
};
export type MutationSignInArgs = {
email: Scalars['String'];
password: Scalars['String'];