Notra/src/components/Block.tsx

74 lines
2.3 KiB
TypeScript

"use client";
import { ChangeEvent } from "react";
import { Lock, LockOpen, Menu, Minus, Plus, X } from "lucide-react";
import { Action, IBlock, ILine } from "@/lib/editorReducer";
import IconOnlyButton from "./IconOnlyButton";
import LineInput from "./LineInput";
export default function Block({
block,
dispatch,
}: {
block: IBlock;
dispatch: React.Dispatch<Action>;
}) {
const handleAddLine = () => {
dispatch({ type: "add_line", blockId: block.id });
}
const handleDeleteLine = () => {
dispatch({ type: "delete_line", blockId: block.id });
}
const handleTagUpdate = (e: ChangeEvent<HTMLInputElement>) => {
dispatch({ type: "update_tag", blockId: block.id, tag: e.target.value });
}
const handleLineUpdate = (e: ChangeEvent<HTMLInputElement>, line: ILine) => {
dispatch({ type: "update_line_text", blockId: block.id, lineId: line.id, text: e.target.value });
}
const handleDeleteBlock = () => {
dispatch({ type: "delete_block", blockId: block.id });
}
const handleToggleLock = () => {
dispatch({ type: "toggle_lock", blockId: block.id });
}
return (
<div className="flex flex-col gap-2 w-full">
<div className="border-2 border-neutral-800 rounded-lg p-3 w-full">
<input
type="text"
placeholder="enter tag..."
className="w-full focus:outline-none"
value={block.tag}
disabled={block.locked}
onChange={handleTagUpdate}
/>
{block.lines.map((line) => (
<LineInput
key={line.id}
value={line.text}
disabled={block.locked}
onChange={(e) => handleLineUpdate(e, line)}
/>
))}
<div className="flex items-center mx-2 mt-2">
<div className="flex gap-2">
<IconOnlyButton onClick={handleAddLine} icon={<Plus size={18} />} />
<IconOnlyButton onClick={handleDeleteLine} icon={<Minus size={18} />} />
</div>
<div className="flex gap-2 ml-auto">
<IconOnlyButton onClick={handleDeleteBlock} icon={<X size={18} />} />
<IconOnlyButton onClick={handleToggleLock} icon={block.locked ? <Lock size={18} /> : <LockOpen size={18} />} alwaysOn={block.locked} />
<IconOnlyButton icon={<Menu size={18} />} />
</div>
</div>
</div>
</div>
);
}