system-praktyk-front/src/management/page/list.tsx
2020-11-14 21:44:08 +01:00

138 lines
5.3 KiB
TypeScript

import { Page } from "@/pages/base";
import { Management } from "@/management/main";
import { Box, Button, CircularProgress, Container, IconButton, Tooltip, Typography } from "@material-ui/core";
import React, { useEffect, useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { useAsyncState } from "@/hooks";
import api from "@/management/api";
import { Async } from "@/components/async";
import MaterialTable, { Action, Column } from "material-table";
import { default as StaticPage } from "@/data/page";
import { Delete, FileFind, Pencil, Refresh } from "mdi-material-ui";
import { encapsulate, one } from "@/helpers";
import { Actions } from "@/components";
import { useSpacing } from "@/styles";
import { useHistory } from "react-router-dom";
import { Add } from "@material-ui/icons";
import { createPortal } from "react-dom";
import { CreateStaticPageDialog } from "@/management/page/create";
import { Confirm } from "@/components/confirm";
export const StaticPageManagement = () => {
const { t } = useTranslation("management");
const [ result, setPagesPromise ] = useAsyncState<StaticPage[]>();
const spacing = useSpacing(2);
const updatePageList = () => {
setPagesPromise(api.page.all());
}
useEffect(updatePageList, []);
const CreateStaticPageAction = () => {
const [ open, setOpen ] = useState<boolean>(false);
const handlePageCreation = async (page: StaticPage) => {
await api.page.save(page);
setOpen(false);
updatePageList();
}
return <>
<Button variant="contained" color="primary" startIcon={ <Add /> } onClick={ () => setOpen(true) }>{ t("create") }</Button>
{ createPortal(
<CreateStaticPageDialog open={ open } onSave={ handlePageCreation } onClose={ () => setOpen(false) }/>,
document.getElementById("modals") as Element
) }
</>
}
const DeleteStaticPageAction = ({ page }: { page: StaticPage }) => {
const handlePageDeletion = async () => {
await api.page.remove(page);
updatePageList();
}
const confirmation = <>
<Trans i18nKey="page.confirm.delete">
Czy na pewno chcesz usunąć stronę <strong>{ page.title.pl }</strong>?
</Trans>
</>;
return <Confirm onConfirm={ handlePageDeletion } content={ confirmation }>
{ action => <Tooltip title={ t("actions.delete") as string }><IconButton onClick={ action }><Delete /></IconButton></Tooltip> }
</Confirm>;
}
const PreviewStaticPageAction = ({ page }: { page: StaticPage }) => {
const history = useHistory();
const handlePagePreview = async () => history.push(`/${page.slug}`);
return <Tooltip title={ t("actions.preview") as string }>
<IconButton onClick={ handlePagePreview }><FileFind /></IconButton>
</Tooltip>;
}
const columns: Column<StaticPage>[] = [
{
render: page => page.title.pl,
title: t("page.field.title"),
},
{
field: "slug",
title: t("page.field.slug"),
},
{
title: t("actions.label"),
render: page => <Actions style={{ margin: "-1rem" }} spacing={ 0 }>
<DeleteStaticPageAction page={ page } />
<PreviewStaticPageAction page={ page } />
</Actions>,
sorting: false,
width: 0,
resizable: false,
removable: false,
searchable: false,
},
];
const PagePreview = ({ page }: { page: StaticPage }) =>
<Box className={ spacing.vertical } p={ 3 }>
<div>
<Typography variant="subtitle2">Polski</Typography>
<Typography variant="h2">{ page.title.pl }</Typography>
<div dangerouslySetInnerHTML={{ __html: page.content.pl }} />
</div>
<div>
<Typography variant="subtitle2">English</Typography>
<Typography variant="h2">{ page.title.en }</Typography>
<div dangerouslySetInnerHTML={{ __html: page.content.en }} />
</div>
</Box>
return <Page>
<Page.Header maxWidth="lg">
<Management.Breadcrumbs>
<Typography color="textPrimary">{ t("page.index.title") }</Typography>
</Management.Breadcrumbs>
<Page.Title>{ t("page.index.title") }</Page.Title>
</Page.Header>
<Container maxWidth="lg" className={ spacing.vertical }>
<Actions>
<CreateStaticPageAction />
<Button onClick={ updatePageList } startIcon={ <Refresh /> }>{ t("refresh") }</Button>
</Actions>
<Async async={ result } keepValue>{
pages => <MaterialTable
title={ <div style={{ display: "flex", alignItems: "center" }}>{ t("page.index.title") } { result.isLoading && <CircularProgress size="1.5rem" style={{ marginLeft: "1rem" }}/> }</div> }
columns={ columns }
data={ pages }
detailPanel={ page => <PagePreview page={ page } /> }
/>
}</Async>
</Container>
</Page>
}
export default StaticPageManagement;