Skip to content

Instantly share code, notes, and snippets.

@ElpixZero
Created November 11, 2019 20:37
Show Gist options
  • Save ElpixZero/0d8f60fbbf620ac1f2d545e37382aea7 to your computer and use it in GitHub Desktop.
Save ElpixZero/0d8f60fbbf620ac1f2d545e37382aea7 to your computer and use it in GitHub Desktop.
import { Button, Grid, Hidden, makeStyles, Theme } from '@material-ui/core';
import { uuid } from '@orbit/utils';
import { NextPage, NextPageContext } from 'next';
import Head from 'next/head';
import { useRouter } from 'next/router';
import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { Document, Page } from 'react-pdf';
import dynamic from 'next/dynamic';
import { withAuth } from '../../components/AuthProvider';
import Layout from '../../components/Layout';
import SmartContractDialog from '../../components/SmartContractDialog';
import {
useUser,
withUser,
WithUserProps,
} from '../../components/UserProvider';
import { memory, remote } from '../../data';
import { DownloadIcon, EyeIcon, SmartContractIcon } from '../../icons';
import {
FileRecord,
PersonRecord,
ResearchMaterialRecord,
SmartContractRecord,
} from '../../types';
const displayName = 'ResearchMaterialPage';
const useStyles = makeStyles(
(theme: Theme) => ({
title: {
fontSize: 18,
marginBottom: 10,
marginTop: 20,
},
authors: {
paddingLeft: 0,
},
author: {
display: 'flex',
justifyContent: 'space-between',
},
info: {
display: 'flex',
flexWrap: 'wrap',
fontSize: 12,
[theme.breakpoints.up('md')]: {
fontSize: 'inherit',
},
'& > dt': {
fontWeight: 700,
marginBottom: 5,
width: '45%',
},
'& > dd': {
marginBottom: 12,
marginLeft: 0,
width: '55%',
},
'& > $description': {
width: '100%',
},
},
description: {
whiteSpace: 'pre-wrap',
},
smartContractCard: {
alignItems: 'center',
borderRadius: theme.spacing(1),
boxShadow: '0px 0px 15px rgba(0, 0, 0, 0.1)',
display: 'flex',
justifyContent: 'center',
minHeight: 400,
padding: theme.spacing(2),
},
smartContracts: {
color: theme.palette.primary.main,
fontSize: 13,
},
smartContractCountIcon: {
marginLeft: 4,
fontSize: 24,
verticalAlign: -6,
},
materialHeader: {
display: 'flex',
justifyContent: 'space-between',
},
}),
{ name: displayName },
);
type ResearchMaterialPageProps = {
authors: PersonRecord[];
file: FileRecord;
hasContract: boolean;
researchMaterial: ResearchMaterialRecord;
};
const ResearchMaterialPage: NextPage<ResearchMaterialPageProps> = ({
authors,
file,
hasContract: hasContractProp,
researchMaterial,
}) => {
const prerenderRef = React.useRef(null);
const DynamicComponentWithNoSSR = dynamic(
() => import('../../components/PrerenderPDF'),
{ ssr: false }
);
const router = useRouter();
const classes = useStyles();
const { t } = useTranslation();
console.log(prerenderRef);
const [user] = useUser();
const isAuthor = Boolean(user && authors.some(({ id }) => id === user.id));
const [hasContract, setHasContract] = React.useState(hasContractProp);
const [dialogOpen, setDialogOpen] = React.useState(false);
const {
attributes: {
description,
field,
keywords,
smartContractCount,
title,
yearEnd,
yearStart,
},
} = researchMaterial;
const onSmartContractCreate = async () => {
if (!user) {
await router.push('/login');
return;
}
const smartContract: SmartContractRecord = {
type: 'smartContract',
id: uuid(),
attributes: {
termsOfUse: 'Смарт-контракт',
},
relationships: {
signatory: {
data: {
type: 'person',
id: user.id,
},
},
researchMaterial: {
data: {
type: researchMaterial.type,
id: researchMaterial.id,
},
},
},
};
try {
await remote.update((t) => t.addRecord(smartContract));
} catch (exception) {
await remote.requestQueue.skip(exception.error);
throw exception.error;
}
setHasContract(true);
setDialogOpen(false);
};
return (
<>
<Layout title={t('Просмотр материала')}>
<Head>
<title>{title}</title>
</Head>
<Grid container data-test-research-page spacing={4}>
<Grid item md={6} xs={12}>
<div className={classes.materialHeader}>
<span>
{yearStart === yearEnd
? yearStart
: `${yearStart} — ${yearEnd}`}
</span>
{smartContractCount > 0 && (
<span className={classes.smartContracts}>
{smartContractCount}
<SmartContractIcon
className={classes.smartContractCountIcon}
/>
</span>
)}
</div>
<h1 className={classes.title}>{title}</h1>
<ul className={classes.authors}>
{authors.map(
({ attributes: { familyName, name, org, surname }, id }) => (
<li className={classes.author} key={id}>
<span>
{surname} {name} {familyName}
</span>
<span>{org}</span>
</li>
),
)}
</ul>
<dl className={classes.info}>
<dt>{t('Область наук')}:</dt>
<dd>{field}</dd>
<dt>{t('Ключевые слова')}:</dt>
<dd>{keywords.join(', ')}</dd>
<dt>{t('Аннотация')}</dt>
<dd className={classes.description}>{description}</dd>
</dl>
<Button
color="primary"
disabled={!(hasContract && file) && !isAuthor}
href={file && file.attributes.filepath}
rel="noreferrer noopener"
startIcon={<DownloadIcon />}
target="_blank"
variant="contained"
>
{t('Загрузить')}
</Button>
</Grid>
<Grid item md={6} xs={12}>
<div ref={prerenderRef} className={classes.smartContractCard}>
{!hasContract && !isAuthor ? (
<Button
color="primary"
onClick={() => setDialogOpen(true)}
startIcon={<EyeIcon />}
variant="contained"
>
<Hidden implementation="css" mdUp>
{t('Заключить смарт-контракт')}
</Hidden>
<Hidden implementation="css" smDown>
{t('Для просмотра заключите смарт-контракт')}
</Hidden>
</Button>
) : (
<DynamicComponentWithNoSSR />
)}
</div>
</Grid>
</Grid>
</Layout>
<SmartContractDialog
onAgree={onSmartContractCreate}
onClose={() => setDialogOpen(false)}
open={dialogOpen}
/>
</>
);
};
ResearchMaterialPage.getInitialProps = async ({
query,
user,
}: NextPageContext & WithUserProps) => {
const id = query.researchMaterialId as string;
let researchMaterial: ResearchMaterialRecord;
try {
researchMaterial = await remote.query((q) =>
q.findRecord({ type: 'researchMaterial', id }),
);
} catch (exception) {
await remote.requestQueue.skip(exception.error);
throw exception.error;
}
let authors: PersonRecord[];
let smartContracts: SmartContractRecord[] = [];
let file: FileRecord;
try {
authors = await memory.query((q) =>
q.findRelatedRecords(researchMaterial, 'authors'),
);
if (user) {
smartContracts = await remote.query((q) =>
q.findRecords('smartContract').filter(
{
relation: 'signatory',
record: user,
},
{
relation: 'research_material',
record: researchMaterial,
},
),
);
}
file = await memory.query((q) =>
q.findRelatedRecord(researchMaterial, 'file'),
);
} catch (exception) {
await memory.requestQueue.skip(exception.error);
throw exception.error;
}
return {
authors,
file,
hasContract: smartContracts.length > 0,
researchMaterial,
};
};
ResearchMaterialPage.displayName = displayName;
export default withAuth({ redirect: false })(withUser(ResearchMaterialPage));
import * as React from 'react';
import { Document, Page } from 'react-pdf';
const PersonalDataForm: React.FunctionComponent = () => {
return (
<Document
file="http://localhost:3000/test.pdf"
onLoadSuccess={() => {}}
>
<Page pageNumber={1} width={422} />
</Document>
);
};
export default PersonalDataForm;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment