138 lines
5.3 KiB
TypeScript
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;
|