94 lines
3.3 KiB
TypeScript
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>
|
|
}
|