74 lines
2.3 KiB
TypeScript
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>
|
|
);
|
|
}
|