144 lines
5.0 KiB
TypeScript
144 lines
5.0 KiB
TypeScript
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>
|
||
);
|
||
}
|