system-praktyk-front/src/components/fileinfo.tsx
2020-11-12 20:16:09 +01:00

94 lines
3.3 KiB
TypeScript

import { InternshipDocument } from "@/api/dto/internship-registration";
import { useAsync } from "@/hooks";
import { DocumentFileInfo } from "@/api/upload";
import React, { useCallback } from "react";
import api from "@/api";
import { Async } from "@/components/async";
import { Button, Grid, Paper, PaperProps, SvgIconProps, Theme, Typography } from "@material-ui/core";
import { makeStyles, createStyles } from "@material-ui/core/styles";
import filesize from "filesize";
import { Actions } from "@/components/actions";
import { useTranslation } from "react-i18next";
import { FileDownloadOutline, FileOutline, FileImageOutline, FilePdfOutline, FileWordOutline } from "mdi-material-ui";
import classNames from "classnames";
const useStyles = makeStyles((theme: Theme) => createStyles({
root: {
padding: theme.spacing(2),
backgroundColor: "#e9f0f5",
},
header: {
color: theme.palette.primary.dark,
},
download: {
color: theme.palette.primary.dark,
},
actions: {
marginTop: theme.spacing(2),
},
icon: {
fontSize: "6rem",
margin: "0 auto",
},
grid: {
display: "flex",
alignItems: "center",
},
iconColumn: {
flex: "0 1 auto",
marginRight: "1rem",
color: theme.palette.primary.dark + "af",
},
asideColumn: {
flex: "1 1 auto"
}
}))
export type FileInfoProps = {
document: InternshipDocument
} & PaperProps;
export type FileIconProps = {
mime: string;
} & SvgIconProps;
export function FileIcon({ mime, ...props }: FileIconProps) {
switch (true) {
case ["application/pdf", "application/x-pdf"].includes(mime):
return <FilePdfOutline {...props} />
case mime === "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
return <FileWordOutline {...props} />
case mime.startsWith("image/"):
return <FileImageOutline {...props} />
default:
return <FileOutline {...props} />
}
}
export const FileInfo = ({ document, ...props }: FileInfoProps) => {
const fileinfo = useAsync<DocumentFileInfo>(useCallback(() => api.upload.fileinfo(document), [document.id]));
const classes = useStyles();
const { t } = useTranslation();
return <Paper variant="outlined" { ...props } className={ classNames(classes.root, props.className) }>
<Async async={ fileinfo }>
{ fileinfo => <div className={ classes.grid }>
<div className={ classes.iconColumn }>
<FileIcon mime={ fileinfo.mime } className={ classes.icon } />
</div>
<aside className={ classes.asideColumn }>
<Typography variant="h5" className={ classes.header }>{ fileinfo.filename }</Typography>
<Typography variant="subtitle2">
{ filesize(fileinfo.size) } { fileinfo.mime }
</Typography>
<Actions className={ classes.actions }>
<Button className={ classes.download } startIcon={ <FileDownloadOutline /> } href={ api.upload.link(document) }>{ t("download") }</Button>
</Actions>
</aside>
</div> }
</Async>
</Paper>
}