chain-frontend/src/widgets/chain-editor/ui/ChainEditor.tsx
2024-03-09 04:48:50 +07:00

144 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { Chain } from "@/entities/chain/schema";
import { useChainState } from "@/entities/chain/model";
import { useNavigate } from "@tanstack/react-router";
import { useState, useRef } from "react";
import humanizeDuration from "humanize-duration";
import { upsertChain } from "@/entities/chain/api/upsert";
import { ActionEditor } from "@/widgets/action-editor";
import { RenameChainButton } from "@/features/rename-chain";
import { DeleteChainButton } from "@/features/delete-chain";
import { Typography, Button } from "@mui/material";
import Breadcrumbs from "@mui/material/Breadcrumbs";
import SettingsIcon from "@mui/icons-material/Settings";
interface ChainEditorProps {
chain: Chain;
}
export default function ChainEditor({ chain }: ChainEditorProps) {
const actionsListRef = useRef<HTMLDivElement>(null);
const [addingNewAction, setAddingNewAction] = useState(false);
const navigate = useNavigate({ from: "/$namespace/$chainId" });
const addCommentAction = useChainState((state) => state.addCommentAction);
if (!chain.actions || chain.actions.length === 0 || addingNewAction)
return (
<div className="flex h-full flex-col">
<div className="flex items-center justify-between">
<Breadcrumbs sx={{ fontSize: "24px" }}>
<Typography
variant="h5"
sx={{ color: "#4C4E64DE", opacity: "60%" }}
className="select-none"
>
{chain.name}
</Typography>
<Typography
variant="h5"
sx={{ color: "#4C4E64DE", opacity: "87%" }}
className="select-none"
>
Новый пост
</Typography>
</Breadcrumbs>
<div className="flex items-center gap-x-5">
<RenameChainButton chain={chain} />
<DeleteChainButton chain={chain} />
</div>
</div>
<div className="flex grow flex-col items-center justify-center">
<ActionEditor
onSave={async (_, action) => {
addCommentAction(chain._id!, action);
await upsertChain(chain);
if (addingNewAction) setAddingNewAction(false);
navigate({ to: "/$namespace/$chainId" });
setTimeout(
() =>
actionsListRef.current?.scrollTo({
behavior: "smooth",
top: actionsListRef.current.scrollHeight,
}),
0,
);
}}
onClose={() => {
if (addingNewAction) setAddingNewAction(false);
}}
canExit={addingNewAction}
/>
</div>
</div>
);
return (
<div className="relative flex h-full flex-col">
<div className="flex items-center justify-between">
<Typography
variant="h5"
sx={{ color: "#4C4E64DE", opacity: "87%" }}
className="select-none"
>
{chain.name}
</Typography>
<div className="flex items-center gap-x-5">
<RenameChainButton chain={chain} />
<DeleteChainButton chain={chain} />
</div>
</div>
<div
ref={actionsListRef}
className="no-scrollbar mt-8 flex grow flex-col items-center gap-y-24 overflow-y-scroll pb-20"
>
{chain.actions.map((action, index) => {
if (action.actionType === "comment")
return (
<div
key={index}
className="relative w-[450px] select-none whitespace-pre-line rounded-md bg-white p-4 text-[#4C4E64DE] opacity-[84%] shadow-lg after:absolute after:left-1/2 after:top-20 after:h-8 after:w-1 after:-translate-x-1/2 after:rounded-md after:bg-[#666CFF] after:opacity-[12%]"
>
{action.text}
</div>
);
return (
<div
key={index}
className="relative flex select-none items-center gap-x-2 text-[#4C4E64DE] opacity-[84%] before:absolute before:-top-6 before:left-1/2 before:h-4 before:w-4 before:-translate-x-1/2 before:rounded-full before:border-[2.5px] before:border-primary after:absolute after:left-1/2 after:top-11 after:h-16 after:w-1 after:-translate-x-1/2 after:rounded-md after:bg-[#666CFF] after:opacity-[12%]"
>
<span>
Ожидание:{" "}
{humanizeDuration(action.waitFor * 1000, { language: "ru" })}
</span>
<button className="flex h-[20px] items-center justify-center rounded-sm bg-[#4C4E648A] bg-opacity-[54%] p-0">
<SettingsIcon sx={{ width: "20px", color: "white" }} />
</button>
</div>
);
})}
<div className="-mt-4">
<Button
variant="outlined"
sx={{
width: "450px",
}}
onClick={() => setAddingNewAction(true)}
>
Добавить
</Button>
</div>
</div>
</div>
);
}