IndexPage fetches professions from the API, add a qualification selector to the Header component

This commit is contained in:
Dawid Wysokiński 2021-03-25 06:29:33 +01:00
parent 2d6e8d8baa
commit 2cb1b1d573
5 changed files with 346 additions and 243 deletions

View File

@ -1,21 +1,58 @@
import { GetStaticProps } from 'next';
import { createClient } from 'libs/graphql';
import {
createClient,
Profession,
Qualification,
Query,
QueryProfessionsArgs,
} from 'libs/graphql';
import { QUERY_PROFESSIONS } from './queries';
import Layout from 'common/Layout/Layout';
import Header from './components/Header/Header';
const IndexPage = () => {
interface IndexPageProps {
professions: Profession[];
qualifications: Qualification[];
}
const IndexPage = ({ qualifications }: IndexPageProps) => {
return (
<Layout transparentTopBar absoluteTopBar padding={false}>
<Header />
<Header qualifications={qualifications} />
</Layout>
);
};
export const getStaticProps: GetStaticProps = async context => {
const pageProps = {};
const getQualificationsFromProfessions = (
professions: Profession[]
): Qualification[] => {
const map = new Map<number, Qualification>();
professions.forEach(profession => {
profession.qualifications.forEach(qualification => {
map.set(qualification.id, qualification);
});
});
return Array.from(map.values());
};
export const getStaticProps: GetStaticProps = async () => {
const pageProps: IndexPageProps = { professions: [], qualifications: [] };
const client = createClient();
try {
const resp = await client.request<
Pick<Query, 'professions'>,
QueryProfessionsArgs
>(QUERY_PROFESSIONS, { sort: ['name ASC'] });
if (Array.isArray(resp.professions?.items)) {
pageProps.professions = resp.professions.items;
pageProps.qualifications = getQualificationsFromProfessions(
resp.professions.items
);
}
} catch (e) {}
return {
props: pageProps,
revalidate: 60,

View File

@ -1,3 +1,6 @@
import { useState } from 'react';
import { Maybe, Qualification } from 'libs/graphql';
import Image from 'next/image';
import { makeStyles } from '@material-ui/core/styles';
import {
@ -6,10 +9,24 @@ import {
Grid,
Typography,
Divider,
TextField,
InputAdornment,
} from '@material-ui/core';
import { Search as SearchIcon } from '@material-ui/icons';
import { Autocomplete } from '@material-ui/lab';
import ThemeProvider from 'libs/material-ui/ThemeProvider';
const Header = () => {
interface HeaderProps {
qualifications: Qualification[];
}
const Header = ({ qualifications = [] }: HeaderProps) => {
const [selectedQualification, setSelectedQualification] = useState<
Maybe<Qualification>
>(null);
const classes = useStyles();
console.log(selectedQualification);
return (
<header className={classes.header}>
<Toolbar />
@ -21,12 +38,43 @@ const Header = () => {
<Typography gutterBottom variant="h1">
Prosta droga do zdania egzaminu zawodowego
</Typography>
<Typography variant="h5">
<Typography variant="h5" gutterBottom>
<strong>zdamegzaminzawodowy.pl</strong> to ogromna baza pytań z
różnych egzaminów zawodowych. Pytania pochodzą z arkuszy z lat
ubiegłych. Wyszukaj poniżej interesującą Cię kwalifikację i
zacznij rozwiązywać testy!
</Typography>
<ThemeProvider cssBaseline={false} paletteType="dark">
<Autocomplete
getOptionLabel={option => `${option.name} (${option.code})`}
noOptionsText="Nie znaleziono żadnej kwalifikacji"
clearText="Wyczyść"
onChange={(e, value) => {
setSelectedQualification(value);
}}
renderInput={params => {
return (
<TextField
{...params}
fullWidth
label="Wpisz nazwę kwalifikacji lub jej oznaczenie"
placeholder="Na przykład: EE.08"
variant="outlined"
color="secondary"
InputProps={{
...params.InputProps,
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
/>
);
}}
options={qualifications}
/>
</ThemeProvider>
</Grid>
<Grid item md={5} xs={12} className={classes.imageWrapper}>
<Image
@ -48,7 +96,6 @@ const useStyles = makeStyles(theme => ({
color: theme.palette.common.white,
position: 'relative',
backgroundColor: theme.palette.primary.dark,
// backgroundImage: `linear-gradient(45deg, ${theme.palette.primary.light}, ${theme.palette.primary.dark})`,
overflowX: 'hidden',
},
container: {

View File

@ -16,26 +16,58 @@ export type Scalars = {
export type QuestionInput = {
content?: Maybe<Scalars['String']>;
export type Question = {
id: Scalars['ID'];
from?: Maybe<Scalars['String']>;
content: Scalars['String'];
explanation?: Maybe<Scalars['String']>;
correctAnswer?: Maybe<Answer>;
qualificationID?: Maybe<Scalars['Int']>;
image?: Maybe<Scalars['Upload']>;
deleteImage?: Maybe<Scalars['Boolean']>;
correctAnswer: Answer;
image?: Maybe<Scalars['String']>;
answerA?: Maybe<Scalars['String']>;
answerAImage?: Maybe<Scalars['Upload']>;
deleteAnswerAImage?: Maybe<Scalars['Boolean']>;
answerAImage?: Maybe<Scalars['String']>;
answerB?: Maybe<Scalars['String']>;
answerBImage?: Maybe<Scalars['Upload']>;
deleteAnswerBImage?: Maybe<Scalars['Boolean']>;
answerBImage?: Maybe<Scalars['String']>;
answerC?: Maybe<Scalars['String']>;
answerCImage?: Maybe<Scalars['Upload']>;
deleteAnswerCImage?: Maybe<Scalars['Boolean']>;
answerCImage?: Maybe<Scalars['String']>;
answerD?: Maybe<Scalars['String']>;
answerDImage?: Maybe<Scalars['Upload']>;
deleteAnswerDImage?: Maybe<Scalars['Boolean']>;
answerDImage?: Maybe<Scalars['String']>;
qualification?: Maybe<Qualification>;
createdAt: Scalars['Time'];
updatedAt: Scalars['Time'];
};
export type UpdateManyUsersInput = {
role?: Maybe<Role>;
activated?: Maybe<Scalars['Boolean']>;
};
export type ProfessionFilter = {
id?: Maybe<Array<Scalars['ID']>>;
idNEQ?: Maybe<Array<Scalars['ID']>>;
slug?: Maybe<Array<Scalars['String']>>;
slugNEQ?: Maybe<Array<Scalars['String']>>;
name?: Maybe<Array<Scalars['String']>>;
nameNEQ?: Maybe<Array<Scalars['String']>>;
nameIEQ?: Maybe<Scalars['String']>;
nameMATCH?: Maybe<Scalars['String']>;
descriptionIEQ?: Maybe<Scalars['String']>;
descriptionMATCH?: Maybe<Scalars['String']>;
qualificationID?: Maybe<Array<Scalars['ID']>>;
createdAt?: Maybe<Scalars['Time']>;
createdAtGT?: Maybe<Scalars['Time']>;
createdAtGTE?: Maybe<Scalars['Time']>;
createdAtLT?: Maybe<Scalars['Time']>;
createdAtLTE?: Maybe<Scalars['Time']>;
};
export type Qualification = {
id: Scalars['ID'];
slug: Scalars['String'];
name: Scalars['String'];
code: Scalars['String'];
formula?: Maybe<Scalars['String']>;
description?: Maybe<Scalars['String']>;
createdAt: Scalars['Time'];
};
export type QuestionFilter = {
@ -54,6 +86,165 @@ export type QuestionFilter = {
createdAtLTE?: Maybe<Scalars['Time']>;
};
export enum Role {
Admin = 'admin',
User = 'user'
}
export enum Answer {
A = 'a',
B = 'b',
C = 'c',
D = 'd'
}
export type UserInput = {
displayName?: Maybe<Scalars['String']>;
password?: Maybe<Scalars['String']>;
email?: Maybe<Scalars['String']>;
role?: Maybe<Role>;
activated?: Maybe<Scalars['Boolean']>;
};
export type Query = {
professions: ProfessionList;
profession?: Maybe<Profession>;
qualifications: QualificationList;
qualification?: Maybe<Qualification>;
questions: QuestionList;
generateTest?: Maybe<Array<Question>>;
users: UserList;
user?: Maybe<User>;
me?: Maybe<User>;
};
export type QueryProfessionsArgs = {
filter?: Maybe<ProfessionFilter>;
limit?: Maybe<Scalars['Int']>;
offset?: Maybe<Scalars['Int']>;
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']>;
offset?: Maybe<Scalars['Int']>;
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']>;
offset?: Maybe<Scalars['Int']>;
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']>;
offset?: Maybe<Scalars['Int']>;
sort?: Maybe<Array<Scalars['String']>>;
};
export type QueryUserArgs = {
id: Scalars['Int'];
};
export type Profession = {
id: Scalars['ID'];
slug: Scalars['String'];
name: Scalars['String'];
description?: Maybe<Scalars['String']>;
createdAt: Scalars['Time'];
qualifications: Array<Qualification>;
};
export type QualificationFilterOr = {
nameMatch?: Maybe<Scalars['String']>;
nameIEQ?: Maybe<Scalars['String']>;
codeMatch?: Maybe<Scalars['String']>;
codeIEQ?: Maybe<Scalars['String']>;
};
export type UserFilter = {
id?: Maybe<Array<Scalars['ID']>>;
idNEQ?: Maybe<Array<Scalars['ID']>>;
activated?: Maybe<Scalars['Boolean']>;
displayName?: Maybe<Array<Scalars['String']>>;
displayNameNEQ?: Maybe<Array<Scalars['String']>>;
displayNameIEQ?: Maybe<Scalars['String']>;
displayNameMATCH?: Maybe<Scalars['String']>;
email?: Maybe<Array<Scalars['String']>>;
emailNEQ?: Maybe<Array<Scalars['String']>>;
emailIEQ?: Maybe<Scalars['String']>;
emailMATCH?: Maybe<Scalars['String']>;
role?: Maybe<Array<Role>>;
roleNEQ?: Maybe<Array<Role>>;
createdAt?: Maybe<Scalars['Time']>;
createdAtGT?: Maybe<Scalars['Time']>;
createdAtGTE?: Maybe<Scalars['Time']>;
createdAtLT?: Maybe<Scalars['Time']>;
createdAtLTE?: Maybe<Scalars['Time']>;
or?: Maybe<UserFilterOr>;
};
export type ProfessionInput = {
name?: Maybe<Scalars['String']>;
description?: Maybe<Scalars['String']>;
};
export type QualificationList = {
total: Scalars['Int'];
items?: Maybe<Array<Qualification>>;
};
export type User = {
id: Scalars['ID'];
displayName: Scalars['String'];
role: Role;
email: Scalars['String'];
activated: Scalars['Boolean'];
createdAt: Scalars['Time'];
};
export type QualificationInput = {
name?: Maybe<Scalars['String']>;
description?: Maybe<Scalars['String']>;
code?: Maybe<Scalars['String']>;
formula?: Maybe<Scalars['String']>;
associateProfession?: Maybe<Array<Scalars['Int']>>;
dissociateProfession?: Maybe<Array<Scalars['Int']>>;
};
export type QuestionList = {
total: Scalars['Int'];
items?: Maybe<Array<Question>>;
};
export type Mutation = {
createProfession?: Maybe<Profession>;
@ -154,73 +345,6 @@ export type ProfessionList = {
items?: Maybe<Array<Profession>>;
};
export type Profession = {
id: Scalars['ID'];
slug: Scalars['String'];
name: Scalars['String'];
description?: Maybe<Scalars['String']>;
createdAt: Scalars['Time'];
};
export enum Answer {
A = 'a',
B = 'b',
C = 'c',
D = 'd'
}
export type UserList = {
total: Scalars['Int'];
items?: Maybe<Array<User>>;
};
export type Question = {
id: Scalars['ID'];
from?: Maybe<Scalars['String']>;
content: Scalars['String'];
explanation?: Maybe<Scalars['String']>;
correctAnswer: Answer;
image?: Maybe<Scalars['String']>;
answerA?: Maybe<Scalars['String']>;
answerAImage?: Maybe<Scalars['String']>;
answerB?: Maybe<Scalars['String']>;
answerBImage?: Maybe<Scalars['String']>;
answerC?: Maybe<Scalars['String']>;
answerCImage?: Maybe<Scalars['String']>;
answerD?: Maybe<Scalars['String']>;
answerDImage?: Maybe<Scalars['String']>;
qualification?: Maybe<Qualification>;
createdAt: Scalars['Time'];
updatedAt: Scalars['Time'];
};
export type UpdateManyUsersInput = {
role?: Maybe<Role>;
activated?: Maybe<Scalars['Boolean']>;
};
export type UserFilter = {
id?: Maybe<Array<Scalars['ID']>>;
idNEQ?: Maybe<Array<Scalars['ID']>>;
activated?: Maybe<Scalars['Boolean']>;
displayName?: Maybe<Array<Scalars['String']>>;
displayNameNEQ?: Maybe<Array<Scalars['String']>>;
displayNameIEQ?: Maybe<Scalars['String']>;
displayNameMATCH?: Maybe<Scalars['String']>;
email?: Maybe<Array<Scalars['String']>>;
emailNEQ?: Maybe<Array<Scalars['String']>>;
emailIEQ?: Maybe<Scalars['String']>;
emailMATCH?: Maybe<Scalars['String']>;
role?: Maybe<Array<Role>>;
roleNEQ?: Maybe<Array<Role>>;
createdAt?: Maybe<Scalars['Time']>;
createdAtGT?: Maybe<Scalars['Time']>;
createdAtGTE?: Maybe<Scalars['Time']>;
createdAtLT?: Maybe<Scalars['Time']>;
createdAtLTE?: Maybe<Scalars['Time']>;
or?: Maybe<UserFilterOr>;
};
export type QualificationFilter = {
id?: Maybe<Array<Scalars['ID']>>;
idNEQ?: Maybe<Array<Scalars['ID']>>;
@ -247,82 +371,31 @@ export type QualificationFilter = {
or?: Maybe<QualificationFilterOr>;
};
export type ProfessionInput = {
name?: Maybe<Scalars['String']>;
description?: Maybe<Scalars['String']>;
export type QuestionInput = {
content?: Maybe<Scalars['String']>;
from?: Maybe<Scalars['String']>;
explanation?: Maybe<Scalars['String']>;
correctAnswer?: Maybe<Answer>;
qualificationID?: Maybe<Scalars['Int']>;
image?: Maybe<Scalars['Upload']>;
deleteImage?: Maybe<Scalars['Boolean']>;
answerA?: Maybe<Scalars['String']>;
answerAImage?: Maybe<Scalars['Upload']>;
deleteAnswerAImage?: Maybe<Scalars['Boolean']>;
answerB?: Maybe<Scalars['String']>;
answerBImage?: Maybe<Scalars['Upload']>;
deleteAnswerBImage?: Maybe<Scalars['Boolean']>;
answerC?: Maybe<Scalars['String']>;
answerCImage?: Maybe<Scalars['Upload']>;
deleteAnswerCImage?: Maybe<Scalars['Boolean']>;
answerD?: Maybe<Scalars['String']>;
answerDImage?: Maybe<Scalars['Upload']>;
deleteAnswerDImage?: Maybe<Scalars['Boolean']>;
};
export type ProfessionFilter = {
id?: Maybe<Array<Scalars['ID']>>;
idNEQ?: Maybe<Array<Scalars['ID']>>;
slug?: Maybe<Array<Scalars['String']>>;
slugNEQ?: Maybe<Array<Scalars['String']>>;
name?: Maybe<Array<Scalars['String']>>;
nameNEQ?: Maybe<Array<Scalars['String']>>;
nameIEQ?: Maybe<Scalars['String']>;
nameMATCH?: Maybe<Scalars['String']>;
descriptionIEQ?: Maybe<Scalars['String']>;
descriptionMATCH?: Maybe<Scalars['String']>;
qualificationID?: Maybe<Array<Scalars['ID']>>;
createdAt?: Maybe<Scalars['Time']>;
createdAtGT?: Maybe<Scalars['Time']>;
createdAtGTE?: Maybe<Scalars['Time']>;
createdAtLT?: Maybe<Scalars['Time']>;
createdAtLTE?: Maybe<Scalars['Time']>;
};
export type QuestionList = {
export type UserList = {
total: Scalars['Int'];
items?: Maybe<Array<Question>>;
};
export enum Role {
Admin = 'admin',
User = 'user'
}
export type UserWithToken = {
token: Scalars['String'];
user: User;
};
export type UserInput = {
displayName?: Maybe<Scalars['String']>;
password?: Maybe<Scalars['String']>;
email?: Maybe<Scalars['String']>;
role?: Maybe<Role>;
activated?: Maybe<Scalars['Boolean']>;
};
export type QualificationList = {
total: Scalars['Int'];
items?: Maybe<Array<Qualification>>;
};
export type QualificationInput = {
name?: Maybe<Scalars['String']>;
description?: Maybe<Scalars['String']>;
code?: Maybe<Scalars['String']>;
formula?: Maybe<Scalars['String']>;
associateProfession?: Maybe<Array<Scalars['Int']>>;
dissociateProfession?: Maybe<Array<Scalars['Int']>>;
};
export type QualificationFilterOr = {
nameMatch?: Maybe<Scalars['String']>;
nameIEQ?: Maybe<Scalars['String']>;
codeMatch?: Maybe<Scalars['String']>;
codeIEQ?: Maybe<Scalars['String']>;
};
export type User = {
id: Scalars['ID'];
displayName: Scalars['String'];
role: Role;
email: Scalars['String'];
activated: Scalars['Boolean'];
createdAt: Scalars['Time'];
items?: Maybe<Array<User>>;
};
export type UserFilterOr = {
@ -332,79 +405,7 @@ export type UserFilterOr = {
emailMATCH?: Maybe<Scalars['String']>;
};
export type Qualification = {
id: Scalars['ID'];
slug: Scalars['String'];
name: Scalars['String'];
code: Scalars['String'];
formula?: Maybe<Scalars['String']>;
description?: Maybe<Scalars['String']>;
createdAt: Scalars['Time'];
};
export type Query = {
professions: ProfessionList;
profession?: Maybe<Profession>;
qualifications: QualificationList;
qualification?: Maybe<Qualification>;
questions: QuestionList;
generateTest?: Maybe<Array<Question>>;
users: UserList;
user?: Maybe<User>;
me?: Maybe<User>;
};
export type QueryProfessionsArgs = {
filter?: Maybe<ProfessionFilter>;
limit?: Maybe<Scalars['Int']>;
offset?: Maybe<Scalars['Int']>;
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']>;
offset?: Maybe<Scalars['Int']>;
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']>;
offset?: Maybe<Scalars['Int']>;
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']>;
offset?: Maybe<Scalars['Int']>;
sort?: Maybe<Array<Scalars['String']>>;
};
export type QueryUserArgs = {
id: Scalars['Int'];
export type UserWithToken = {
token: Scalars['String'];
user: User;
};

View File

@ -1,16 +1,32 @@
import { useMemo } from 'react';
import createTheme from './createTheme';
import { ThemeProvider as MuiThemeProvider } from '@material-ui/styles';
import { CssBaseline } from '@material-ui/core';
import createTheme from './createTheme';
import { PaletteOptions } from '@material-ui/core/styles/createPalette';
interface ThemeProviderProps {
children?: React.ReactNode;
paletteType?: PaletteOptions['type'];
cssBaseline?: boolean;
}
function ThemeProvider({ children }: ThemeProviderProps) {
function ThemeProvider({
children,
paletteType,
cssBaseline = true,
}: ThemeProviderProps) {
const theme = useMemo(() => createTheme(paletteType), [paletteType]);
return (
<MuiThemeProvider theme={createTheme()}>
{children}
<CssBaseline />
<MuiThemeProvider theme={theme}>
{cssBaseline ? (
<>
{children}
<CssBaseline />
</>
) : (
children
)}
</MuiThemeProvider>
);
}

View File

@ -3,9 +3,10 @@ import {
responsiveFontSizes,
Theme,
} from '@material-ui/core/styles';
import { PaletteOptions } from '@material-ui/core/styles/createPalette';
import { blue, pink } from '@material-ui/core/colors';
const createTheme = (): Theme => {
const createTheme = (paletteType?: PaletteOptions['type']): Theme => {
return responsiveFontSizes(
createMuiTheme({
typography: {
@ -14,6 +15,7 @@ const createTheme = (): Theme => {
},
},
palette: {
type: paletteType,
primary: {
main: blue['A200'],
},